Go to the documentation of this file.
41 namespace functionObjects
80 writeHeaderValue(
os,
"CofR", coordSysPtr_->origin());
82 writeCommented(
os,
"Time");
83 writeTabbed(
os,
"(total_x total_y total_z)");
84 writeTabbed(
os,
"(pressure_x pressure_y pressure_z)");
85 writeTabbed(
os,
"(viscous_x viscous_y viscous_z)");
89 writeTabbed(
os,
"(porous_x porous_y porous_z)");
103 writeHeaderValue(
os,
"bins", nBin_);
104 writeHeaderValue(
os,
"start", binMin_);
105 writeHeaderValue(
os,
"end", binMax_);
106 writeHeaderValue(
os,
"delta", binDx_);
107 writeHeaderValue(
os,
"direction", binDir_);
110 writeCommented(
os,
"x co-ords :");
113 binPoints[pointi] = (binMin_ + (pointi + 1)*binDx_)*binDir_;
114 os <<
tab << binPoints[pointi].x();
118 writeCommented(
os,
"y co-ords :");
121 os <<
tab << binPoints[pointi].y();
125 writeCommented(
os,
"z co-ords :");
128 os <<
tab << binPoints[pointi].z();
133 writeCommented(
os,
"Time");
135 for (label j = 0; j < nBin_; j++)
138 os <<
tab <<
jn <<
"(total_x total_y total_z)"
139 <<
tab <<
jn <<
"(pressure_x pressure_y pressure_z)"
140 <<
tab <<
jn <<
"(viscous_x viscous_y viscous_z)";
144 os <<
tab <<
jn <<
"(porous_x porous_y porous_z)";
159 coordSysPtr_.clear();
162 if (
dict.readIfPresent<
point>(
"CofR", origin))
176 if (
dict.found(coordinateSystem::typeName_()))
184 coordinateSystem::typeName_()
203 if (directForceDensity_)
205 if (!foundObject<volVectorField>(fDName_))
208 <<
"Could not find " << fDName_ <<
" in database"
216 !foundObject<volVectorField>(UName_)
217 || !foundObject<volScalarField>(pName_)
222 <<
"Could not find U: " << UName_ <<
" or p:" << pName_
227 if (rhoName_ !=
"rhoInf" && !foundObject<volScalarField>(rhoName_))
230 <<
"Could not find rho:" << rhoName_
248 scalar geomMin = GREAT;
249 scalar geomMax = -GREAT;
250 for (
const label patchi : patchSet_)
254 geomMin =
min(
min(d), geomMin);
255 geomMax =
max(
max(d), geomMax);
271 for (
const label zonei : cellZoneIDs)
273 const cellZone& cZone = mesh_.cellZones()[zonei];
275 geomMin =
min(
min(d), geomMin);
276 geomMax =
max(
max(d), geomMax);
281 reduce(geomMin, minOp<scalar>());
282 reduce(geomMax, maxOp<scalar>());
285 geomMax = 1.0001*(geomMax - geomMin) + geomMin;
288 if (binMin_ == GREAT)
292 if (binMax_ == GREAT)
297 binDx_ = (binMax_ - binMin_)/scalar(nBin_);
300 binPoints_.setSize(nBin_);
303 binPoints_[i] = (i + 0.5)*binDir_*binDx_;
329 lookupObjectRef<volVectorField>(scopedName(
"force"));
334 lookupObjectRef<volVectorField>(scopedName(
"moment"));
347 const auto&
U = lookupObject<volVectorField>(UName_);
349 if (foundObject<cmpTurbModel>(cmpTurbModel::propertiesName))
351 const cmpTurbModel&
turb =
352 lookupObject<cmpTurbModel>(cmpTurbModel::propertiesName);
354 return turb.devRhoReff(
U);
356 else if (foundObject<icoTurbModel>(icoTurbModel::propertiesName))
359 lookupObject<icoTurbModel>(icoTurbModel::propertiesName);
365 const fluidThermo&
thermo =
370 else if (foundObject<transportModel>(
"transportProperties"))
372 const transportModel& laminarT =
373 lookupObject<transportModel>(
"transportProperties");
377 else if (foundObject<dictionary>(
"transportProperties"))
380 lookupObject<dictionary>(
"transportProperties");
389 <<
"No valid model for viscous stress calculation"
406 else if (foundObject<transportModel>(
"transportProperties"))
408 const transportModel& laminarT =
409 lookupObject<transportModel>(
"transportProperties");
411 return rho()*laminarT.nu();
413 else if (foundObject<dictionary>(
"transportProperties"))
416 lookupObject<dictionary>(
"transportProperties");
425 <<
"No valid model for dynamic viscosity calculation"
435 if (rhoName_ ==
"rhoInf")
442 mesh_.time().timeName(),
450 return(lookupObject<volScalarField>(rhoName_));
461 if (rhoName_ !=
"rhoInf")
464 <<
"Dynamic pressure is expected but kinematic is provided."
483 force_[0][0] +=
sum(fN);
484 force_[1][0] +=
sum(fT);
485 force_[2][0] +=
sum(fP);
486 moment_[0][0] +=
sum(Md^fN);
487 moment_[1][0] +=
sum(Md^fT);
488 moment_[2][0] +=
sum(Md^fP);
496 label bini =
min(
max(floor(dd[i]/binDx_), 0), force_[0].size() - 1);
498 force_[0][bini] += fN[i];
499 force_[1][bini] += fT[i];
500 force_[2][bini] += fP[i];
501 moment_[0][bini] += Md[i]^fN[i];
502 moment_[1][bini] += Md[i]^fT[i];
503 moment_[2][bini] += Md[i]^fP[i];
523 auto& force = lookupObjectRef<volVectorField>(scopedName(
"force"));
527 auto& moment = lookupObjectRef<volVectorField>(scopedName(
"moment"));
528 vectorField& pm = moment.boundaryFieldRef()[patchi];
547 auto& force = lookupObjectRef<volVectorField>(scopedName(
"force"));
548 auto& moment = lookupObjectRef<volVectorField>(scopedName(
"moment"));
552 label celli = cellIDs[i];
553 force[celli] += fN[i] + fT[i] + fP[i];
554 moment[celli] = Md[i]^force[celli];
561 const string& descriptor,
571 vector total = pressure + viscous + porous;
573 Log <<
" Sum of " << descriptor.c_str() <<
nl
574 <<
" Total : " << total <<
nl
575 <<
" Pressure : " << pressure <<
nl
576 <<
" Viscous : " << viscous <<
nl;
580 Log <<
" Porous : " << porous <<
nl;
585 Ostream&
os = osPtr();
587 writeCurrentTime(
os);
607 const auto& coordSys = coordSysPtr_();
609 writeIntegratedForceMoment
612 coordSys.localVector(force_[0]),
613 coordSys.localVector(force_[1]),
614 coordSys.localVector(force_[2]),
618 writeIntegratedForceMoment
621 coordSys.localVector(moment_[0]),
622 coordSys.localVector(moment_[1]),
623 coordSys.localVector(moment_[2]),
637 if ((nBin_ == 1) || !writeToFile())
646 for (label i = 1; i <
f[0].size(); i++)
648 f[0][i] +=
f[0][i-1];
649 f[1][i] +=
f[1][i-1];
650 f[2][i] +=
f[2][i-1];
654 Ostream&
os = osPtr();
656 writeCurrentTime(
os);
660 vector total =
f[0][i] +
f[1][i] +
f[2][i];
678 const auto& coordSys = coordSysPtr_();
680 List<Field<vector>> lf(3);
681 List<Field<vector>> lm(3);
682 lf[0] = coordSys.localVector(force_[0]);
683 lf[1] = coordSys.localVector(force_[1]);
684 lf[2] = coordSys.localVector(force_[2]);
685 lm[0] = coordSys.localVector(moment_[0]);
686 lm[1] = coordSys.localVector(moment_[1]);
687 lm[2] = coordSys.localVector(moment_[2]);
689 writeBinnedForceMoment(lf, forceBinFilePtr_);
690 writeBinnedForceMoment(lm, momentBinFilePtr_);
716 directForceDensity_(false),
720 coordSysPtr_(nullptr),
728 binCumulative_(true),
749 fvMeshFunctionObject(
name, obr,
dict),
750 writeFile(mesh_,
name),
761 directForceDensity_(false),
765 coordSysPtr_(nullptr),
773 binCumulative_(true),
804 initialised_ =
false;
808 directForceDensity_ =
dict.getOrDefault(
"directForceDensity",
false);
811 mesh_.boundaryMesh().patchSet
816 if (directForceDensity_)
819 if (
dict.readIfPresent<
word>(
"fD", fDName_))
827 if (
dict.readIfPresent<
word>(
"p", pName_))
831 if (
dict.readIfPresent<word>(
"U", UName_))
835 if (
dict.readIfPresent<word>(
"rho", rhoName_))
837 Info<<
" rho: " << rhoName_ <<
endl;
841 if (rhoName_ ==
"rhoInf")
843 rhoRef_ =
dict.get<scalar>(
"rhoInf");
844 Info<<
" Freestream density (rhoInf) set to " << rhoRef_ <<
endl;
848 if (
dict.readIfPresent<scalar>(
"pRef", pRef_))
850 Info<<
" Reference pressure (pRef) set to " << pRef_ <<
endl;
854 dict.readIfPresent(
"porosity", porosity_);
857 Info<<
" Including porosity effects" <<
endl;
861 Info<<
" Not including porosity effects" <<
endl;
864 if (
dict.found(
"binData"))
866 Info<<
" Activated data bins" <<
endl;
867 const dictionary& binDict(
dict.subDict(
"binData"));
868 nBin_ = binDict.get<label>(
"nBin");
873 <<
"Number of bins (nBin) must be zero or greater"
883 Info<<
" Employing " << nBin_ <<
" bins" <<
endl;
884 if (binDict.readIfPresent(
"min", binMin_))
886 Info<<
" - min : " << binMin_ <<
endl;
888 if (binDict.readIfPresent(
"max", binMax_))
890 Info<<
" - max : " << binMax_ <<
endl;
893 binCumulative_ = binDict.get<
bool>(
"cumulative");
894 Info<<
" - cumuluative : " << binCumulative_ <<
endl;
896 binDir_ = binDict.get<
vector>(
"direction");
898 Info<<
" - direction : " << binDir_ <<
endl;
902 writeFields_ =
dict.getOrDefault(
"writeFields",
false);
906 Info<<
" Fields will be written" <<
endl;
925 mesh_.objectRegistry::store(forcePtr);
933 scopedName(
"moment"),
944 mesh_.objectRegistry::store(momentPtr);
957 const point& origin = coordSysPtr_->origin();
959 if (directForceDensity_)
965 for (
const label patchi : patchSet_)
967 vectorField Md(mesh_.C().boundaryField()[patchi] - origin);
986 addToFields(patchi, Md, fN, fT, fP);
988 applyBins(Md, fN, fT, fP, mesh_.C().boundaryField()[patchi]);
995 const surfaceVectorField::Boundary& Sfb = mesh_.Sf().boundaryField();
997 tmp<volSymmTensorField> tdevRhoReff = devRhoReff();
998 const volSymmTensorField::Boundary& devRhoReffb
999 = tdevRhoReff().boundaryField();
1002 scalar pRef = pRef_/
rho(
p);
1004 for (
const label patchi : patchSet_)
1006 vectorField Md(mesh_.C().boundaryField()[patchi] - origin);
1010 rho(
p)*Sfb[patchi]*(
p.boundaryField()[patchi] - pRef)
1013 vectorField fT(Sfb[patchi] & devRhoReffb[patchi]);
1017 addToFields(patchi, Md, fN, fT, fP);
1019 applyBins(Md, fN, fT, fP, mesh_.C().boundaryField()[patchi]);
1029 const HashTable<const porosityModel*> models =
1030 obr_.lookupClass<porosityModel>();
1035 <<
"Porosity effects requested, but no porosity models found "
1036 <<
"in the database"
1043 porosityModel& pm =
const_cast<porosityModel&
>(*iter());
1047 const labelList& cellZoneIDs = pm.cellZoneIDs();
1049 for (
const label zonei : cellZoneIDs)
1051 const cellZone& cZone = mesh_.cellZones()[zonei];
1059 addToFields(cZone, Md, fDummy, fDummy, fP);
1061 applyBins(Md, fDummy, fDummy, fP, d);
1075 return sum(force_[0]) +
sum(force_[1]) +
sum(force_[2]);
1081 return sum(moment_[0]) +
sum(moment_[1]) +
sum(moment_[2]);
1101 setResult(
"normalForce",
sum(force_[0]));
1102 setResult(
"tangentialForce",
sum(force_[1]));
1103 setResult(
"porousForce",
sum(force_[2]));
1105 setResult(
"normalMoment",
sum(moment_[0]));
1106 setResult(
"tangentialMoment",
sum(moment_[1]));
1107 setResult(
"porousMoment",
sum(moment_[2]));
1117 lookupObject<volVectorField>(scopedName(
"force")).write();
1118 lookupObject<volVectorField>(scopedName(
"moment")).write();
virtual vector forceEff() const
List< label > labelList
A List of labels.
const dimensionSet dimPressure
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Defines the attributes of an object for which implicit objectRegistry management is supported,...
tmp< GeometricField< typename outerProduct< vector, Type >::type, fvPatchField, volMesh >> grad(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
tmp< volScalarField > mu() const
A class for handling words, derived from Foam::string.
const labelList & cellZoneIDs() const
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
virtual tmp< volScalarField > nu() const =0
const dimensionedScalar mu
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
Calculates the forces and moments by integrating the pressure and skin-friction forces over a given l...
A class for managing temporary objects.
static constexpr const zero Zero
const dimensionSet dimDensity
static const word dictName
dimensionedScalar jn(const int n, const dimensionedScalar &ds)
bool read(const char *buf, int32_t &val)
autoPtr< OFstream > momentBinFilePtr_
IOdictionary transportProperties(IOobject("transportProperties", runTime.constant(), mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
void writeBinHeader(const word &header, Ostream &os) const
Fundamental fluid thermodynamic properties.
Basic thermodynamics type based on the use of fitting functions for cp, h, s obtained from the templa...
static bool master(const label communicator=worldComm)
Ostream & endl(Ostream &os)
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
static void writeHeader(Ostream &os, const word &fieldName)
void writeIntegratedForceMoment(const string &descriptor, const vectorField &fm0, const vectorField &fm1, const vectorField &fm2, autoPtr< OFstream > &osPtr) const
const dimensionSet dimForce
Vector< Cmpt > & normalise()
Provides several methods to convert an input pressure field into derived forms, including:
Specialization of Foam::functionObject for an Foam::fvMesh, providing a reference to the Foam::fvMesh...
void setCoordinateSystem(const dictionary &dict, const word &e3Name=word::null, const word &e1Name=word::null)
label min(const labelHashSet &set, label minValue=labelMax)
Abstract base-class for Time/database function objects.
autoPtr< OFstream > forceFilePtr_
autoPtr< OFstream > momentFilePtr_
Field< vector > vectorField
Specialisation of Field<T> for vector.
virtual void calcForcesMoment()
dimensioned< vector > dimensionedVector
Dimensioned vector obtained from generic dimensioned type.
Registry of regIOobjects.
tmp< volScalarField > rho() const
virtual bool read(const dictionary &dict)
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
virtual tmp< vectorField > force(const volVectorField &U, const volScalarField &rho, const volScalarField &mu)
virtual vector momentEff() const
Generic templated field type.
A patch is a list of labels that address the faces in the global face list.
tmp< volSymmTensorField > devRhoReff() const
static autoPtr< coordinateSystem > New(word modelType, const objectRegistry &obr, const dictionary &dict)
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
virtual bool read(const dictionary &)
label max(const labelHashSet &set, label maxValue=labelMin)
autoPtr< OFstream > forceBinFilePtr_
const dimensionSet dimViscosity
void addToFields(const label patchi, const vectorField &Md, const vectorField &fN, const vectorField &fT, const vectorField &fP)
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
virtual bool read(const dictionary &dict)
OBJstream os(runTime.globalPath()/outputName)
Macros for easy insertion into run-time selection tables.
Generic dimensioned Type class.
void writeIntegratedHeader(const word &header, Ostream &os) const
Vector< scalar > vector
A scalar version of the templated Vector.
void writeBinnedForceMoment(const List< Field< vector >> &fm, autoPtr< OFstream > &osPtr) const
errorManipArg< error, int > exit(error &err, const int errNo=1)
Base-class for all transport models used by the incompressible turbulence models.
void readFields(const typename GeoFieldType::Mesh &mesh, const IOobjectList &objects, const wordHashSet &selectedFields, LIFOStack< regIOobject * > &storedObjects)
A HashTable similar to std::unordered_map.
GeometricField< vector, fvPatchField, volMesh > volVectorField
static void listCombineGather(const List< commsStruct > &comms, List< T > &Value, const CombineOp &cop, const int tag, const label comm)
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Top level model for porosity models.
#define FatalErrorInFunction
void applyBins(const vectorField &Md, const vectorField &fN, const vectorField &fT, const vectorField &fP, const vectorField &d)
forAllConstIters(mixture.phases(), phase)
const vectorField::subField faceCentres() const
virtual autoPtr< OFstream > createFile(const word &name, scalar timeValue) const
addToRunTimeSelectionTable(functionObject, ObukhovLength, dictionary)
A Cartesian coordinate system.
Boundary & boundaryFieldRef(const bool updateAccessTime=true)
Templated wrapper class to provide compressible turbulence models thermal diffusivity based thermal t...
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Calculate the gradient of the given field.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
fileName::Type type(const fileName &name, const bool followLink=true)
A List of wordRe with additional matching capabilities.
static tmp< T > New(Args &&... args)
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
defineTypeNameAndDebug(ObukhovLength, 0)
Reads fields from the time directories and adds them to the mesh database for further post-processing...
word name(const expressions::valueTypeCode typeCode)
Base class for writing single files from the function objects.
Templated abstract base class for single-phase incompressible turbulence models.
#define FatalIOErrorInFunction(ios)
bool empty() const noexcept
virtual bool writeToFile() const
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
static const GeometricField< Type, PatchField, GeoMesh > & null()
static void listCombineScatter(const List< commsStruct > &comms, List< T > &Value, const int tag, const label comm)
IncompressibleTurbulenceModel< transportModel > turbulenceModel
Generic GeometricField class.
compressible::turbulenceModel & turb
#define WarningInFunction
dimensionedSymmTensor twoSymm(const dimensionedSymmTensor &dt)
forces(const forces &)=delete
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
const Boundary & boundaryField() const
dimensionedSymmTensor dev(const dimensionedSymmTensor &dt)