40 namespace functionObjects
56 const word forceType(
dict.lookup(
"type"));
61 if (
dict.found(
"binData"))
81 ?
"(pressure viscous porous)"
82 :
"(pressure viscous)"
87 case fileID::mainFile:
92 writeCoRValueHeader(
file(i));
93 writeCommented(
file(i),
"Time");
95 writeCoRHeader(
file(i));
98 <<
"forces" << forceTypes <<
tab
99 <<
"moments" << forceTypes;
103 case fileID::binsFile:
108 writeHeaderValue(
file(i),
"bins", nBin_);
109 writeHeaderValue(
file(i),
"start", binMin_);
110 writeHeaderValue(
file(i),
"delta", binDx_);
111 writeHeaderValue(
file(i),
"direction", binDir_);
114 writeCommented(
file(i),
"x co-ords :");
117 binPoints[pointi] = (binMin_ + (pointi + 1)*binDx_)*binDir_;
118 file(i) <<
tab << binPoints[pointi].x();
122 writeCommented(
file(i),
"y co-ords :");
125 file(i) <<
tab << binPoints[pointi].y();
129 writeCommented(
file(i),
"z co-ords :");
132 file(i) <<
tab << binPoints[pointi].z();
136 writeCommented(
file(i),
"Time");
138 for (
label j = 0; j < nBin_; j++)
141 const word f(
"forces" +
jn + forceTypes);
142 const word m(
"moments" +
jn + forceTypes);
152 <<
"Unhandled file index: " << i
168 if (directForceDensity_)
173 <<
"Could not find " << fDName_ <<
" in database."
187 <<
"Could not find " << UName_ <<
", " << pName_
198 <<
"Could not find " << rhoName_
215 const word& modelName = momentumTransportModel::typeName;
216 const word phaseModelName =
221 if (obr_.foundObject<icoModel>(modelName))
224 obr_.lookupObject<icoModel>(modelName);
228 else if (obr_.foundObject<cmpModel>(modelName))
230 const cmpModel& model =
231 obr_.lookupObject<cmpModel>(modelName);
233 return alpha()*model.devTau();
235 else if (obr_.foundObject<phaseIcoModel>(phaseModelName))
237 const phaseIcoModel& model =
238 obr_.lookupObject<phaseIcoModel>(phaseModelName);
240 return rho()*model.devSigma();
242 else if (obr_.foundObject<phaseCmpModel>(phaseModelName))
244 const phaseCmpModel& model =
245 obr_.lookupObject<phaseCmpModel>(phaseModelName);
247 return model.devTau();
249 else if (obr_.foundObject<
dictionary>(
"physicalProperties"))
254 obr_.lookupObject<
dictionary>(
"physicalProperties");
270 <<
"No valid model for viscous stress calculation"
285 const word& modelName = momentumTransportModel::typeName;
286 const word phaseModelName =
291 if (obr_.foundObject<icoModel>(modelName))
294 obr_.lookupObject<icoModel>(modelName);
296 return rho()*model.
nu();
298 else if (obr_.foundObject<cmpModel>(modelName))
300 const cmpModel& model =
301 obr_.lookupObject<cmpModel>(modelName);
303 return model.rho()*model.nu();
305 else if (obr_.foundObject<phaseIcoModel>(phaseModelName))
307 const phaseIcoModel& model =
308 obr_.lookupObject<phaseIcoModel>(phaseModelName);
310 return rho()*model.nu();
312 else if (obr_.foundObject<phaseCmpModel>(phaseModelName))
314 const phaseCmpModel& model =
315 obr_.lookupObject<phaseCmpModel>(phaseModelName);
317 return model.rho()*model.nu();
319 else if (obr_.foundObject<
dictionary>(
"physicalProperties"))
324 obr_.lookupObject<
dictionary>(
"physicalProperties");
338 <<
"No valid model for dynamic viscosity calculation"
348 if (rhoName_ ==
"rhoInf")
375 if (rhoName_ !=
"rhoInf")
378 <<
"Dynamic pressure is expected but kinematic is provided."
425 ).boundaryField()[
patchi];
441 force_[0][0] +=
sum(fN);
442 force_[1][0] +=
sum(fT);
443 force_[2][0] +=
sum(fP);
444 moment_[0][0] +=
sum(Md^fN);
445 moment_[1][0] +=
sum(Md^fT);
446 moment_[2][0] +=
sum(Md^fP);
454 label bini =
min(
max(floor(dd[i]/binDx_), 0), force_[0].size() - 1);
456 force_[0][bini] += fN[i];
457 force_[1][bini] += fT[i];
458 force_[2][bini] += fP[i];
459 moment_[0][bini] += Md[i]^fN[i];
460 moment_[1][bini] += Md[i]^fT[i];
461 moment_[2][bini] += Md[i]^fP[i];
486 <<
" sum of forces:" <<
nl
487 <<
" pressure : " <<
sum(force_[0]) <<
nl
488 <<
" viscous : " <<
sum(force_[1]) <<
nl
489 <<
" porous : " <<
sum(force_[2]) <<
nl
490 <<
" sum of moments:" <<
nl
491 <<
" pressure : " <<
sum(moment_[0]) <<
nl
492 <<
" viscous : " <<
sum(moment_[1]) <<
nl
493 <<
" porous : " <<
sum(moment_[2])
496 writeTime(
file(fileID::mainFile));
497 writeCofR(
file(fileID::mainFile));
502 <<
sum(force_[0]) <<
setw(1) <<
' '
503 <<
sum(force_[1]) <<
setw(1) <<
' '
504 <<
sum(force_[2]) <<
setw(3) <<
") ("
505 <<
sum(moment_[0]) <<
setw(1) <<
' '
506 <<
sum(moment_[1]) <<
setw(1) <<
' '
507 <<
sum(moment_[2]) <<
setw(1) <<
')';
512 <<
sum(force_[0]) <<
setw(1) <<
' '
513 <<
sum(force_[1]) <<
setw(3) <<
") ("
514 <<
sum(moment_[0]) <<
setw(1) <<
' '
515 <<
sum(moment_[1]) <<
setw(1) <<
')';
534 for (
label i = 1; i <
f[0].size(); i++)
536 f[0][i] +=
f[0][i-1];
537 f[1][i] +=
f[1][i-1];
538 f[2][i] +=
f[2][i-1];
540 m[0][i] += m[0][i-1];
541 m[1][i] += m[1][i-1];
542 m[2][i] += m[2][i-1];
546 writeTime(
file(fileID::binsFile));
553 file(fileID::binsFile)
555 <<
f[0][i] <<
setw(1) <<
' '
556 <<
f[1][i] <<
setw(1) <<
' '
557 <<
f[2][i] <<
setw(3) <<
") ("
558 << m[0][i] <<
setw(1) <<
' '
559 << m[1][i] <<
setw(1) <<
' '
560 << m[2][i] <<
setw(1) <<
')';
564 file(fileID::binsFile)
566 <<
f[0][i] <<
setw(1) <<
' '
567 <<
f[1][i] <<
setw(3) <<
") ("
568 << m[0][i] <<
setw(1) <<
' '
569 << m[1][i] <<
setw(1) <<
')';
593 rhoName_(
word::null),
594 phaseName_(
word::null),
595 directForceDensity_(false),
605 binCumulative_(true),
626 rhoName_(
word::null),
627 phaseName_(
word::null),
628 directForceDensity_(false),
638 binCumulative_(true),
657 initialised_ =
false;
661 directForceDensity_ =
dict.lookupOrDefault(
"directForceDensity",
false);
665 patchSet_ = patchSet(
dict);
667 if (directForceDensity_)
670 fDName_ =
dict.lookupOrDefault<
word>(
"fD",
"fD");
698 if (rhoName_ ==
"rhoInf")
700 dict.lookup(
"rhoInf") >> rhoRef_;
704 pRef_ =
dict.lookupOrDefault<scalar>(
"pRef", 0.0);
707 dict.readIfPresent(
"porosity", porosity_);
710 Log <<
" Including porosity effects" <<
endl;
714 Log <<
" Not including porosity effects" <<
endl;
717 if (
dict.found(
"binData"))
720 binDict.
lookup(
"nBin") >> nBin_;
725 <<
"Number of bins (nBin) must be zero or greater"
728 else if ((nBin_ == 0) || (nBin_ == 1))
733 force_[i].setSize(1);
734 moment_[i].setSize(1);
740 binDict.
lookup(
"direction") >> binDir_;
741 binDir_ /=
mag(binDir_);
744 scalar binMax = -great;
750 binMin_ =
min(
min(d), binMin_);
751 binMax =
max(
max(d), binMax);
758 binMax = 1.0001*(binMax - binMin_) + binMin_;
760 binDx_ = (binMax - binMin_)/scalar(nBin_);
763 binPoints_.setSize(nBin_);
766 binPoints_[i] = (i + 0.5)*binDir_*binDx_;
769 binDict.
lookup(
"cumulative") >> binCumulative_;
774 force_[i].setSize(nBin_);
775 moment_[i].setSize(nBin_);
783 force_[0].setSize(1);
784 force_[1].setSize(1);
785 force_[2].setSize(1);
786 moment_[0].setSize(1);
787 moment_[1].setSize(1);
788 moment_[2].setSize(1);
791 resetNames(createFileNames(
dict));
809 if (directForceDensity_)
814 mesh_.Sf().boundaryField();
822 mesh_.C().boundaryField()[
patchi] - CofR
842 applyBins(Md, fN, fT, fP, mesh_.C().boundaryField()[
patchi]);
850 mesh_.Sf().boundaryField();
854 tdevTau().boundaryField();
857 const scalar pRef = pRef_/
rho(
p);
865 mesh_.C().boundaryField()[
patchi] - CofR
873 *(
p.boundaryField()[
patchi] - pRef)
880 applyBins(Md, fN, fT, fP, mesh_.C().boundaryField()[
patchi]);
896 <<
"Porosity effects requested, but no porosity models found "
914 applyBins(Md, fDummy, fDummy, fP, d);
933 return sum(force_[0]) +
sum(force_[1]) +
sum(force_[2]);
939 return sum(moment_[0]) +
sum(moment_[1]) +
sum(moment_[2]);
951 calcForcesMoments(CofR());
#define forAll(list, i)
Loop across all elements in list.
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Macros for easy insertion into run-time selection tables.
Generic GeometricBoundaryField class.
Generic GeometricField class.
const Boundary & boundaryField() const
Return const-reference to the boundary field.
static const GeometricField< Type, PatchField, GeoMesh > & null()
Return a null geometric field.
static tmp< GeometricField< Type, PatchField, GeoMesh > > New(const word &name, const Internal &, const PtrList< PatchField< Type >> &, const HashPtrTable< Source > &=HashPtrTable< Source >())
Return a temporary field constructed from name,.
An STL-conforming hash table.
bool empty() const
Return true if the hash table is empty.
static word groupName(Name name, const word &group)
void append(const T &)
Append an element at the end of the list.
void size(const label)
Override size to be inconsistent with allocated storage.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
static void listCombineGather(const List< commsStruct > &comms, List< T > &Value, const CombineOp &cop, const int tag, const label comm)
static void listCombineScatter(const List< commsStruct > &comms, List< T > &Value, const int tag, const label comm)
Scatter data. Reverse of combineGather.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
static bool master(const label communicator=0)
Am I the master process.
Base class for single-phase compressible turbulence models.
A list of keyword definitions, which are a keyword followed by any number of values (e....
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Calculates the forces and moments by integrating the pressure and skin-friction forces over a given l...
virtual void calcForcesMoments()
Calculate the forces and moments.
tmp< volScalarField > alpha() const
Get the volume fraction field.
void initialise()
Initialise the fields.
virtual void writeCoRHeader(Ostream &file)
Write the time varying centre of rotation column header.
tmp< volSymmTensorField > devTau() const
Return the effective viscous stress (laminar + turbulent).
void applyBins(const vectorField &Md, const vectorField &fN, const vectorField &fT, const vectorField &fP, const vectorField &d)
Accumulate bin data.
tmp< volScalarField > mu() const
Dynamic viscosity field.
virtual vector forceEff() const
Return the total force.
forcesBase(const word &name, const Time &runTime, const dictionary &dict)
Construct from Time and dictionary.
virtual vector momentEff() const
Return the total moment.
virtual void writeCoRValueHeader(Ostream &file)
Write the constant centre of rotation value in the header.
void writeBins()
Helper function to write bin data.
virtual ~forcesBase()
Destructor.
virtual void writeFileHeader(const label i)
Output file header information.
void writeForces()
Helper function to write force data.
tmp< volScalarField > rho() const
Return rho if specified otherwise rhoRef.
fileID
Enumeration for ensuring the right file is accessed.
virtual bool execute()
Execute, currently does nothing.
virtual bool write()
Write the forces.
virtual void writeCofR(Ostream &file)
Write the time varying centre of rotation.
virtual bool read(const dictionary &)
Read the forces data.
wordList createFileNames(const dictionary &dict) const
Create file names for forces and bins.
Specialisation of Foam::functionObject for an Foam::fvMesh, providing a reference to the Foam::fvMesh...
functionObject base class for creating, maintaining and writing log files e.g. integrated of averaged...
const wordList & names() const
Return the list of log file names.
virtual bool write()
Write function.
virtual bool read(const dictionary &)
Read optional controls.
Base class for single-phase incompressible turbulence models.
virtual tmp< volSymmTensorField > devSigma() const
Return the effective stress tensor.
virtual tmp< volScalarField > nu() const
Return the laminar viscosity.
Registry of regIOobjects.
Templated abstract base class for multiphase compressible turbulence models.
Templated abstract base class for multiphase incompressible turbulence models.
A base class for physical properties.
A patch is a list of labels that address the faces in the global face list.
const vectorField::subField faceCentres() const
Return face centres.
Top level model for porosity models.
const word & zoneName() const
Return const access to the cell zone name.
virtual tmp< vectorField > force(const volVectorField &U, const volScalarField &rho, const volScalarField &mu) const
Return the force over the cell zone(s)
A class for managing temporary objects.
A class for handling words, derived from string.
static const word null
An empty word.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Calculate the gradient of the given field.
volScalarField alpha(IOobject("alpha", runTime.name(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE), lambda *max(Ua &U, zeroSensitivity))
#define WarningInFunction
Report a warning using Foam::Warning.
#define Log
Report write to Foam::Info if the local log switch is true.
const dimensionedScalar mu
Atomic mass unit.
defineTypeNameAndDebug(adjustTimeStepToCombustion, 0)
tmp< VolField< typename outerProduct< vector, Type >::type > > grad(const SurfaceField< Type > &ssf)
void writeHeader(std::ostream &, const bool isBinary, const std::string &title)
Write header.
dimensionedSymmTensor dev(const dimensionedSymmTensor &dt)
errorManipArg< error, int > exit(error &err, const int errNo=1)
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
const dimensionSet dimPressure
Ostream & endl(Ostream &os)
Add newline and flush stream.
word name(const bool)
Return a word representation of a bool.
const dimensionSet dimKinematicViscosity
Omanip< int > setw(const int i)
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
dimensionedSymmTensor twoSymm(const dimensionedSymmTensor &dt)
errorManip< error > abort(error &err)
const dimensionSet dimless
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
const dimensionSet dimDensity
dimensioned< scalar > mag(const dimensioned< Type > &)
dimensionedScalar jn(const int n, const dimensionedScalar &ds)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.