60 magU = magU.weightedAverage(
mesh_.V());
67void Foam::functionObjects::comfort::initWallInfo()
const
69 if (wallInfoInit_)
return;
71 const fvBoundaryMesh&
patches = mesh_.boundary();
82 wallPatchIDs_.setSize(wallCount);
84 scalar localWallArea = 0;
91 wallPatchIDs_[wallIndex++] = patchi;
92 localWallArea +=
sum(
p.magSf());
96 wallArea_ = localWallArea;
97 reduce(wallArea_, sumOp<scalar>());
110 <<
"The calculated mean wall radiation temperature is out of\n"
111 <<
"the bounds specified in EN ISO 7730:2005\n"
112 <<
"Valid range is 10 degC < T < 40 degC\n"
113 <<
"The actual value is: " << (Trad_.value() - 273.15) <<
nl
126 lookupObject<volScalarField>(
"T").boundaryField();
129 scalar TareaIntegral = 0;
133 const label patchi = wallPatchIDs_[wi];
135 const fvPatch&
p = Tp.
patch();
139 reduce(TareaIntegral, sumOp<scalar>());
144 TareaIntegral/(wallArea_ + VSMALL)
151 <<
"The calculated mean wall radiation temperature is out of\n"
152 <<
"the bounds specified in EN ISO 7730:2005\n"
153 <<
"Valid range is 10 degC < T < 40 degC\n"
154 <<
"The actual value is: " << (TradMean.value() - 273.15) <<
nl
162Foam::tmp<Foam::volScalarField> Foam::functionObjects::comfort::pSat()
const
169 tmp<volScalarField> tpSat;
172 if (pSat_.value() == 0)
174 const auto&
T = lookupObject<volScalarField>(
"T");
177 tpSat = kPaToPa*
exp(
A -
B/(
T +
C));
188Foam::tmp<Foam::volScalarField> Foam::functionObjects::comfort::Tcloth
224 auto& Tcl = tTcl.ref();
230 auto& hcNatural = thcNatural.ref();
236 Tcl = 0.5*(Tcl + Tcl.prevIter());
244 pos(hcForced - hcNatural)*hcForced
245 +
neg0(hcForced - hcNatural)*hcNatural;
251 - Icl_*factor3*fcl_*(
pow4(Tcl) - Trad4)
252 - Icl_*fcl_*hc*(Tcl -
T);
258 }
while (!converged(Tcl) && ++iter < maxClothIter_);
260 if (iter == maxClothIter_)
263 <<
"The surface cloth temperature 'Tcl' did not converge within "
264 << iter <<
" iterations" <<
nl;
271bool Foam::functionObjects::comfort::converged
276 const auto& curr =
phi.primitiveField();
277 const auto& prev =
phi.prevIter().primitiveField();
280 if (
mag(curr[i] - prev[i]) >= tolerance_)
299 clothing_(
"clothing",
dimless, 0),
303 relHumidity_(
"relHumidity",
dimless, 0.5),
310 wallInfoInit_(false),
327 clothing_.readIfPresent(
dict);
328 metabolicRate_.readIfPresent(
dict);
329 extWork_.readIfPresent(
dict);
330 pSat_.readIfPresent(
dict);
331 tolerance_ =
dict.getOrDefault(
"tolerance", 1
e-4);
332 maxClothIter_ =
dict.getOrDefault(
"maxClothIter", 100);
333 meanVelocity_ =
dict.getOrDefault(
"meanVelocity",
false);
336 if (
dict.found(relHumidity_.name()))
338 relHumidity_.read(
dict);
339 relHumidity_ /= scalar(100);
343 if (
dict.found(Trad_.name()))
352 Icl_.value() <= 0.078
353 ? 1.0 + 1.290*Icl_.value()
354 : 1.05 + 0.645*Icl_.value();
372 const auto&
T = lookupObject<volScalarField>(
"T");
381 mesh_.time().timeName(),
407 dimless/metabolicRateSI.dimensions(),
429 metaDiff.value() < factor8.value() ? 0 : 0.42
434 Info<<
"Calculating the predicted mean vote (PMV)" <<
endl;
440 (factor1*
exp(factor2*metabolicRateSI) + factor3)
453 - factor7*(metabolicRateSI - extWorkSI - factor8)
456 - factor9*metabolicRateSI*(factor10 - pSatRH)
459 - factor11*metabolicRateSI*(factor12 -
T)
462 - factor13*fcl_*(
pow4(TclothFld) - Trad4)
465 - fcl_*hc*(TclothFld -
T)
469 Info<<
"Calculating the predicted percentage of dissatisfaction (PPD)"
474 100 - 95*
exp(-0.03353*
pow4(PMV()) - 0.21790*
sqr(PMV()));
476 Info<<
"Calculating the draught rating (DR)\n";
485 Umag.clamp_range(Umin, Umax);
494 mesh_.time().timeName(),
502 if (foundObject<volScalarField>(
"k"))
504 const auto&
k = lookupObject<volScalarField>(
"k");
505 TI =
sqrt(2/3*
k)/Umag;
517 correctUnit*(factor12 -
T)*
pow(Umag - Umin, 0.62)*(pre*Umag*TI + C1);
523 word fieldNamePMV =
"PMV";
524 word fieldNamePPD =
"PPD";
525 word fieldNameDR =
"DR";
526 word fieldNameTop =
"Top";
530 store(fieldNamePMV, PMV)
532 &&
store(fieldNameDR, DR)
533 &&
store(fieldNameTop, Top)
543 && writeObject(
"PPD")
545 && writeObject(
"Top")
static const Foam::dimensionedScalar C("", Foam::dimTemperature, 234.5)
static const Foam::dimensionedScalar A("", Foam::dimPressure, 611.21)
static const Foam::dimensionedScalar B("", Foam::dimless, 18.678)
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
static tmp< GeometricField< scalar, fvPatchField, volMesh > > New(const word &name, IOobjectOption::registerOption regOpt, const Mesh &mesh, const dimensionSet &dims, const word &patchFieldType=fvPatchField< scalar >::calculatedType())
void clamp_range(const dimensioned< MinMax< Type > > &range)
Clamp field values (in-place) to the specified range.
Internal & ref(const bool updateAccessTime=true)
Same as internalFieldRef().
GeometricBoundaryField< scalar, fvPatchField, volMesh > Boundary
@ NO_REGISTER
Do not request registration (bool: false).
Defines the attributes of an object for which implicit objectRegistry management is supported,...
bool contains(const T &val) const
True if the value is within the range (inclusive check).
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Dimension set for the base types, which can be used to implement rigorous dimension checking for alge...
const dimensionSet & dimensions() const noexcept
Return const reference to dimensions.
const Type & value() const noexcept
Return const reference to value.
Abstract base-class for Time/database function objects.
virtual bool read(const dictionary &dict)
Read and set the function object if its data have changed.
Calculates the thermal comfort quantities predicted mean vote (PMV), predicted percentage of dissatis...
virtual bool read(const dictionary &dict)
Read the function-object dictionary.
comfort(const word &name, const Time &runTime, const dictionary &dict)
Construct from name, Time and dictionary.
virtual bool execute()
Execute the function-object operations.
virtual bool write()
Write the function-object results.
const fvMesh & mesh_
Reference to the fvMesh.
fvMeshFunctionObject(const fvMeshFunctionObject &)=delete
No copy construct.
const ObjectType & lookupObject(const word &fieldName) const
Lookup and return object (eg, a field) from the (sub) objectRegistry.
bool foundObject(const word &fieldName) const
Find object (eg, a field) in the (sub) objectRegistry.
bool store(word &fieldName, const tmp< ObjectType > &tfield, bool cacheable=false)
Store the field in the (sub) objectRegistry under the given name.
bool writeObject(const word &fieldName)
Write field if present in the (sub) objectRegistry.
const DimensionedField< scalar, volMesh > & V() const
Return cell volumes.
const fvPatch & patch() const noexcept
Return the patch.
A class for managing temporary objects.
A class for handling words, derived from Foam::string.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
static const Foam::scalarMinMax Tbounds(283.15, 313.15)
const polyBoundaryMesh & patches
#define WarningInFunction
Report a warning using Foam::Warning.
Function objects are OpenFOAM utilities to ease workflow configurations and enhance workflows.
const dimensionSet dimPressure
Type weightedSum(const UList< scalar > &weights, const UList< Type > &fld)
The local weighted sum (integral) of a field, using the mag() of the weights.
dimensionedScalar pos(const dimensionedScalar &ds)
dimensionedScalar exp(const dimensionedScalar &ds)
const dimensionSet dimless
Dimensionless.
bool read(const char *buf, int32_t &val)
Same as readInt32.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
dimensionedScalar pow3(const dimensionedScalar &ds)
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
GeometricField< scalar, fvPatchField, volMesh > volScalarField
const dimensionSet dimVelocity
messageStream Info
Information stream (stdout output on master, null elsewhere).
MinMax< scalar > scalarMinMax
A scalar min/max range.
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Ostream & endl(Ostream &os)
Add newline and flush stream.
const dimensionSet dimTemperature(0, 0, 0, 1, 0, 0, 0)
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void reduce(T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce).
dimensionedScalar pow4(const dimensionedScalar &ds)
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1, const label comm)
static constexpr const zero Zero
Global zero (0).
bool isType(const U &obj)
Check if typeid of the object and Type are identical.
dimensionedScalar neg0(const dimensionedScalar &ds)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
const dimensionSet dimMass(1, 0, 0, 0, 0, 0, 0)
fvPatchField< scalar > fvPatchScalarField
dimensionedScalar pow025(const dimensionedScalar &ds)
constexpr char nl
The newline '\n' character (0x0a).
#define forAll(list, i)
Loop across all elements in list.