35#include "porosityModel.H"
36#include "turbulentTransportModel.H"
37#include "turbulentFluidThermoModel.H"
38#include "addToRunTimeSelectionTable.H"
39#include "cartesianCS.H"
56 const word& name)
const
58 return this->name() +
":" + name;
65 if (writeToFile() && !forceFilePtr_.valid())
67 forceFilePtr_ = createFile(
"force");
68 writeIntegratedHeader(
"Force", forceFilePtr_());
69 momentFilePtr_ = createFile(
"moment");
70 writeIntegratedHeader(
"Moment", momentFilePtr_());
74 forceBinFilePtr_ = createFile(
"forceBin");
75 writeBinHeader(
"Force", forceBinFilePtr_());
76 momentBinFilePtr_ = createFile(
"momentBin");
77 writeBinHeader(
"Moment", momentBinFilePtr_());
82 localForceFilePtr_ = createFile(
"localForce");
83 writeIntegratedHeader(
"Force", localForceFilePtr_());
84 localMomentFilePtr_ = createFile(
"localMoment");
85 writeIntegratedHeader(
"Moment", localMomentFilePtr_());
89 localForceBinFilePtr_ = createFile(
"localForceBin");
90 writeBinHeader(
"Force", localForceBinFilePtr_());
91 localMomentBinFilePtr_ = createFile(
"localMomentBin");
92 writeBinHeader(
"Moment", localMomentBinFilePtr_());
105 writeHeader(os, header);
106 writeHeaderValue(os,
"CofR", coordSys_.origin());
108 writeCommented(os,
"Time");
109 writeTabbed(os,
"(total_x total_y total_z)");
110 writeTabbed(os,
"(pressure_x pressure_y pressure_z)");
111 writeTabbed(os,
"(viscous_x viscous_y viscous_z)");
115 writeTabbed(os,
"(porous_x porous_y porous_z)");
128 writeHeader(os, header +
" bins");
129 writeHeaderValue(os,
"bins", nBin_);
130 writeHeaderValue(os,
"start", binMin_);
131 writeHeaderValue(os,
"delta", binDx_);
132 writeHeaderValue(os,
"direction", binDir_);
133 vectorField binPoints(nBin_);
134 writeCommented(os,
"x co-ords :");
137 binPoints[pointi] = (binMin_ + (pointi + 1) * binDx_) * binDir_;
138 os << tab << binPoints[pointi].x();
142 writeCommented(os,
"y co-ords :");
145 os << tab << binPoints[pointi].y();
149 writeCommented(os,
"z co-ords :");
152 os << tab << binPoints[pointi].z();
157 writeCommented(os,
"Time");
159 for (label j = 0; j < nBin_; j++)
161 const word jn(Foam::name(j) +
':');
162 os << tab << jn <<
"(total_x total_y total_z)"
163 << tab << jn <<
"(pressure_x pressure_y pressure_z)"
164 << tab << jn <<
"(viscous_x viscous_y viscous_z)";
168 os << tab << jn <<
"(porous_x porous_y porous_z)";
184 if (directForceDensity_)
186 if (!foundObject<volVectorField>(fDName_))
189 <<
"Could not find " << fDName_ <<
" in database"
197 !foundObject<volVectorField>(UName_)
198 || !foundObject<volScalarField>(pName_)
202 <<
"Could not find U: " << UName_ <<
" or p:" << pName_
207 if (rhoName_ !=
"rhoInf" && !foundObject<volScalarField>(rhoName_))
210 <<
"Could not find rho:" << rhoName_
224 const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
227 scalar binMax = -GREAT;
229 for (
const label patchi : patchSet_)
231 const polyPatch& pp = pbm[patchi];
232 scalarField d(pp.faceCentres() & binDir_);
233 binMin_ =
min(
min(d), binMin_);
234 binMax =
max(
max(d), binMax);
240 const HashTable<const porosityModel*> models =
241 obr_.lookupClass<porosityModel>();
242 const scalarField dd(mesh_.C() & binDir_);
243 forAllConstIter(HashTable<const porosityModel*>, models, iter)
245 const porosityModel& pm = * iter();
246 const labelList& cellZoneIDs = pm.cellZoneIDs();
248 for (
const label zonei : cellZoneIDs)
250 const cellZone& cZone = mesh_.cellZones()[zonei];
251 const scalarField d(dd, cZone);
252 binMin_ =
min(
min(d), binMin_);
253 binMax =
max(
max(d), binMax);
258 reduce(binMin_, minOp<scalar>());
259 reduce(binMax, maxOp<scalar>());
262 binMax = 1.0001 * (binMax - binMin_) + binMin_;
263 binDx_ = (binMax - binMin_) / scalar(nBin_);
265 binPoints_.setSize(nBin_);
268 binPoints_[
i] = (
i + 0.5) * binDir_ * binDx_;
275 force_[
i].setSize(nBin_, vector::zero);
276 moment_[
i].setSize(nBin_, vector::zero);
292 volVectorField& force =
293 lookupObjectRef<volVectorField>(fieldName(
"force"));
294 force == dimensionedVector(force.dimensions(), Zero);
295 volVectorField& moment =
296 lookupObjectRef<volVectorField>(fieldName(
"moment"));
297 moment == dimensionedVector(moment.dimensions(), Zero);
302Foam::tmp<Foam::volSymmTensorField>
305 typedef compressible::turbulenceModel cmpTurbModel;
306 typedef incompressible::turbulenceModel icoTurbModel;
308 if (foundObject<cmpTurbModel>(cmpTurbModel::propertiesName))
310 const cmpTurbModel& turb =
311 lookupObject<cmpTurbModel>(cmpTurbModel::propertiesName);
312 return turb.devRhoReff();
314 else if (foundObject<icoTurbModel>(icoTurbModel::propertiesName))
316 const incompressible::turbulenceModel& turb =
317 lookupObject<icoTurbModel>(icoTurbModel::propertiesName);
318 return rho() * turb.devReff();
320 else if (foundObject<fluidThermo>(fluidThermo::dictName))
322 const fluidThermo&
thermo =
323 lookupObject<fluidThermo>(fluidThermo::dictName);
324 const volVectorField&
U = lookupObject<volVectorField>(UName_);
325 return -
thermo.mu() * dev(twoSymm(fvc::grad(
U)));
327 else if (foundObject<transportModel>(
"transportProperties"))
329 const transportModel& laminarT =
330 lookupObject<transportModel>(
"transportProperties");
331 const volVectorField&
U = lookupObject<volVectorField>(UName_);
332 return -
rho() * laminarT.nu() * dev(twoSymm(fvc::grad(
U)));
334 else if (foundObject<dictionary>(
"transportProperties"))
337 lookupObject<dictionary>(
"transportProperties");
339 const volVectorField&
U = lookupObject<volVectorField>(UName_);
340 return -
rho() *
nu * dev(twoSymm(fvc::grad(
U)));
345 <<
"No valid model for viscous stress calculation"
347 return volSymmTensorField::null();
354 if (foundObject<fluidThermo>(basicThermo::dictName))
356 const fluidThermo&
thermo =
357 lookupObject<fluidThermo>(basicThermo::dictName);
360 else if (foundObject<transportModel>(
"transportProperties"))
362 const transportModel& laminarT =
363 lookupObject<transportModel>(
"transportProperties");
364 return rho() * laminarT.nu();
366 else if (foundObject<dictionary>(
"transportProperties"))
369 lookupObject<dictionary>(
"transportProperties");
381 <<
"No valid model for dynamic viscosity calculation"
383 return volScalarField::null();
390 if (rhoName_ ==
"rhoInf")
392 return tmp<volScalarField>::New
397 mesh_.time().timeName(),
401 dimensionedScalar(
"rho", dimDensity, rhoRef_)
405 return (lookupObject<volScalarField>(rhoName_));
412 if (
p.dimensions() == dimPressure)
417 if (rhoName_ !=
"rhoInf")
420 <<
"Dynamic pressure is expected but kinematic is provided."
430 const vectorField& Md,
431 const vectorField& fN,
432 const vectorField& fT,
433 const vectorField& fP,
439 force_[0][0] += sum(fN);
440 force_[1][0] += sum(fT);
441 force_[2][0] += sum(fP);
442 moment_[0][0] += sum(Md ^ fN);
443 moment_[1][0] += sum(Md ^ fT);
444 moment_[2][0] += sum(Md ^ fP);
448 scalarField dd((d & binDir_) - binMin_);
451 label bini =
min(
max(floor(dd[
i] / binDx_), 0), force_[0].size() - 1);
452 force_[0][bini] += fN[
i];
453 force_[1][bini] += fT[
i];
454 force_[2][bini] += fP[
i];
455 moment_[0][bini] += Md[
i] ^ fN[
i];
456 moment_[1][bini] += Md[
i] ^ fT[
i];
457 moment_[2][bini] += Md[
i] ^ fP[
i];
466 const vectorField& Md,
467 const vectorField& fN,
468 const vectorField& fT,
469 const vectorField& fP
477 volVectorField& force =
478 lookupObjectRef<volVectorField>(fieldName(
"force"));
479 vectorField& pf = force.boundaryFieldRef()[patchi];
481 volVectorField& moment =
482 lookupObjectRef<volVectorField>(fieldName(
"moment"));
483 vectorField& pm = moment.boundaryFieldRef()[patchi];
490 const labelList& cellIDs,
491 const vectorField& Md,
492 const vectorField& fN,
493 const vectorField& fT,
494 const vectorField& fP
502 volVectorField& force =
503 lookupObjectRef<volVectorField>(fieldName(
"force"));
504 volVectorField& moment =
505 lookupObjectRef<volVectorField>(fieldName(
"moment"));
508 label celli = cellIDs[
i];
509 force[celli] += fN[
i] + fT[
i] + fP[
i];
510 moment[celli] += Md[
i];
517 const string& descriptor,
518 const vectorField& fm0,
519 const vectorField& fm1,
520 const vectorField& fm2,
521 autoPtr<OFstream>& osPtr
524 vector pressure = sum(fm0);
525 vector viscous = sum(fm1);
526 vector porous = sum(fm2);
527 vector total = pressure + viscous + porous;
528 Log <<
" Sum of " << descriptor.c_str() << nl
529 <<
" Total : " << total << nl
530 <<
" Pressure : " << pressure << nl
531 <<
" Viscous : " << viscous << nl;
535 Log <<
" Porous : " << porous << nl;
540 Ostream& os = osPtr();
542 writeCurrentTime(os);
562 Log << type() <<
" " << name() <<
" write:" << nl;
563 writeIntegratedForceMoment
571 writeIntegratedForceMoment
582 writeIntegratedForceMoment
585 coordSys_.localVector(force_[0]),
586 coordSys_.localVector(force_[1]),
587 coordSys_.localVector(force_[2]),
590 writeIntegratedForceMoment
593 coordSys_.localVector(moment_[0]),
594 coordSys_.localVector(moment_[1]),
595 coordSys_.localVector(moment_[2]),
606 const List<Field<vector >> & fm,
607 autoPtr<OFstream>& osPtr
610 if ((nBin_ == 1) || !writeToFile())
615 List<Field<vector >> f(fm);
618 for (label
i = 1;
i < f[0].size();
i++)
620 f[0][
i] += f[0][
i - 1];
621 f[1][
i] += f[1][
i - 1];
622 f[2][
i] += f[2][
i - 1];
626 Ostream& os = osPtr();
628 writeCurrentTime(os);
634 vector total = f[0][
i] + f[1][
i] + f[2][
i];
640 os << tab << f[2][
i];
650 writeBinnedForceMoment(force_, forceBinFilePtr_);
651 writeBinnedForceMoment(moment_, momentBinFilePtr_);
654 List<Field<vector >> lf(3);
655 List<Field<vector >> lm(3);
656 lf[0] = coordSys_.localVector(force_[0]);
657 lf[1] = coordSys_.localVector(force_[1]);
658 lf[2] = coordSys_.localVector(force_[2]);
659 lm[0] = coordSys_.localVector(moment_[0]);
660 lm[1] = coordSys_.localVector(moment_[1]);
661 lm[2] = coordSys_.localVector(moment_[2]);
662 writeBinnedForceMoment(lf, localForceBinFilePtr_);
663 writeBinnedForceMoment(lm, localMomentBinFilePtr_);
674 const dictionary& dict,
678 fvMeshFunctionObject(name,
runTime, dict),
679 writeFile(mesh_, name),
686 localForceFilePtr_(),
687 localMomentFilePtr_(),
688 localForceBinFilePtr_(),
689 localMomentBinFilePtr_(),
693 rhoName_(word::null),
694 directForceDensity_(false),
706 binCumulative_(true),
721 const objectRegistry& obr,
722 const dictionary& dict,
726 fvMeshFunctionObject(name, obr, dict),
727 writeFile(mesh_, name),
734 localForceFilePtr_(),
735 localMomentFilePtr_(),
736 localForceBinFilePtr_(),
737 localMomentBinFilePtr_(),
741 rhoName_(word::null),
742 directForceDensity_(false),
754 binCumulative_(true),
787 fvMeshFunctionObject::read(dict);
788 writeFile::read(dict);
789 initialised_ =
false;
790 Info << type() <<
" " << name() <<
":" << nl;
791 directForceDensity_ = dict.lookupOrDefault(
"directForceDensity",
false);
792 const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
793 patchSet_ = pbm.patchSet(dict.get<wordRes>(
"patches"));
795 if (directForceDensity_)
798 fDName_ = dict.lookupOrDefault<word>(
"fD",
"fD");
803 pName_ = dict.lookupOrDefault<word>(
"p",
"p");
804 UName_ = dict.lookupOrDefault<word>(
"U",
"U");
805 rhoName_ = dict.lookupOrDefault<word>(
"rho",
"rho");
808 if (rhoName_ ==
"rhoInf")
810 dict.readEntry(
"rhoInf", rhoRef_);
814 pRef_ = dict.lookupOrDefault<scalar>(
"pRef", 0.0);
817 localSystem_ =
false;
821 if (!dict.readIfPresent<point>(
"CofR", coordSys_.origin()))
825 if (dict.found(coordinateSystem::typeName_()))
829 coordinateSystem::New
831 obr_, dict, coordinateSystem::typeName_()
836 coordSys_ = coordSystem::cartesian(dict);
841 dict.readIfPresent(
"porosity", porosity_);
845 Info <<
" Including porosity effects" << endl;
849 Info <<
" Not including porosity effects" << endl;
851 if (dict.found(
"binData"))
853 const dictionary& binDict(dict.subDict(
"binData"));
854 binDict.readEntry(
"nBin", nBin_);
858 FatalIOErrorInFunction(dict)
859 <<
"Number of bins (nBin) must be zero or greater"
860 << exit(FatalIOError);
869 binDict.readEntry(
"cumulative", binCumulative_);
870 binDict.readEntry(
"direction", binDir_);
874 writeFields_ = dict.lookupOrDefault(
"writeFields",
false);
878 Info <<
" Fields will be written" << endl;
879 volVectorField* forcePtr
892 dimensionedVector(dimForce, Zero)
895 mesh_.objectRegistry::store(forcePtr);
896 volVectorField* momentPtr
909 dimensionedVector(dimForce * dimLength, Zero)
912 mesh_.objectRegistry::store(momentPtr);
923 if (directForceDensity_)
925 const volVectorField& fD = lookupObject<volVectorField>(fDName_);
926 const surfaceVectorField::Boundary& Sfb = mesh_.Sf().boundaryField();
928 for (
const label patchi : patchSet_)
932 mesh_.C().boundaryField()[patchi] - coordSys_.origin()
934 scalarField sA(mag(Sfb[patchi]));
940 Sfb[patchi] & fD.boundaryField()[patchi]
944 vectorField fT(sA * fD.boundaryField()[patchi] - fN);
946 vectorField fP(Md.size(), Zero);
947 addToFields(patchi, Md, fN, fT, fP);
948 applyBins(Md, fN, fT, fP, mesh_.C().boundaryField()[patchi]);
953 const volScalarField&
p = lookupObject<volScalarField>(pName_);
954 const surfaceVectorField::Boundary& Sfb = mesh_.Sf().boundaryField();
955 tmp<volSymmTensorField> tdevRhoReff = devRhoReff();
956 const volSymmTensorField::Boundary& devRhoReffb
957 = tdevRhoReff().boundaryField();
959 scalar pRef = pRef_ /
rho(
p);
961 for (
const label patchi : patchSet_)
965 mesh_.C().boundaryField()[patchi] - coordSys_.origin()
969 rho(
p) * Sfb[patchi] * (
p.boundaryField()[patchi] - pRef)
971 vectorField fT(Sfb[patchi] & devRhoReffb[patchi]);
972 vectorField fP(Md.size(), Zero);
973 addToFields(patchi, Md, fN, fT, fP);
974 applyBins(Md, fN, fT, fP, mesh_.C().boundaryField()[patchi]);
980 const volVectorField&
U = lookupObject<volVectorField>(UName_);
981 const volScalarField
rho(this->
rho());
982 const volScalarField mu(this->mu());
983 const HashTable<const porosityModel*> models =
984 obr_.lookupClass<porosityModel>();
989 <<
"Porosity effects requested, but no porosity models found "
994 forAllConstIters(models, iter)
997 porosityModel& pm =
const_cast<porosityModel&
>(* iter());
998 vectorField fPTot(pm.force(
U,
rho, mu));
999 const labelList& cellZoneIDs = pm.cellZoneIDs();
1001 for (
const label zonei : cellZoneIDs)
1003 const cellZone& cZone = mesh_.cellZones()[zonei];
1004 const vectorField d(mesh_.C(), cZone);
1005 const vectorField fP(fPTot, cZone);
1006 const vectorField Md(d - coordSys_.origin());
1007 const vectorField fDummy(Md.size(), Zero);
1008 addToFields(cZone, Md, fDummy, fDummy, fP);
1009 applyBins(Md, fDummy, fDummy, fP, d);
1014 Pstream::listCombineGather(force_, plusEqOp<vectorField>());
1015 Pstream::listCombineGather(moment_, plusEqOp<vectorField>());
1016 Pstream::listCombineScatter(force_);
1017 Pstream::listCombineScatter(moment_);
1023 return sum(force_[0]) + sum(force_[1]) + sum(force_[2]);
1029 return sum(moment_[0]) + sum(moment_[1]) + sum(moment_[2]);
1037 if (Pstream::master())
1046 setResult(
"normalForce", sum(force_[0]));
1047 setResult(
"tangentialForce", sum(force_[1]));
1048 setResult(
"porousForce", sum(force_[2]));
1049 setResult(
"normalMoment", sum(moment_[0]));
1050 setResult(
"tangentialMoment", sum(moment_[1]));
1051 setResult(
"porousMoment", sum(moment_[2]));
1060 lookupObject<volVectorField>(fieldName(
"force")).write();
1061 lookupObject<volVectorField>(fieldName(
"moment")).write();
1070 return sum(force_[0]);
1075 return sum(force_[1]);
1086#include "porosityModel.H"
1087#include "turbulentTransportModel.H"
1088#include "turbulentFluidThermoModel.H"
1089#include "addToRunTimeSelectionTable.H"
1108 const dictionary& dict
1111 DynamicList<word>
names(1);
1112 const word forceType(dict.lookup(
"type"));
1114 names.append(forceType);
1116 if (dict.found(
"binData"))
1118 const dictionary& binDict(dict.subDict(
"binData"));
1119 label nb = readLabel(binDict.lookup(
"nBin"));
1124 names.append(forceType +
"_bins");
1139 writeHeader(file(
i),
"Forces");
1140 writeHeaderValue(file(
i),
"CofR",
coordSys_.origin());
1141 writeCommented(file(
i),
"Time");
1142 const word forceTypes(
"(pressure viscous porous)");
1144 <<
"forces" << forceTypes << tab
1145 <<
"moments" << forceTypes;
1151 <<
"localForces" << forceTypes << tab
1152 <<
"localMoments" << forceTypes;
1161 writeHeader(file(
i),
"Force bins");
1162 writeHeaderValue(file(
i),
"bins",
nBin_);
1163 writeHeaderValue(file(
i),
"start",
binMin_);
1164 writeHeaderValue(file(
i),
"delta",
binDx_);
1165 writeHeaderValue(file(
i),
"direction",
binDir_);
1166 vectorField binPoints(
nBin_);
1167 writeCommented(file(
i),
"x co-ords :");
1168 forAll(binPoints, pointi)
1171 file(
i) << tab << binPoints[pointi].x();
1175 writeCommented(file(
i),
"y co-ords :");
1176 forAll(binPoints, pointi)
1178 file(
i) << tab << binPoints[pointi].y();
1182 writeCommented(file(
i),
"z co-ords :");
1183 forAll(binPoints, pointi)
1185 file(
i) << tab << binPoints[pointi].z();
1189 writeCommented(file(
i),
"Time");
1190 const word binForceTypes(
"[pressure,viscous,porous]");
1192 for (label j = 0; j <
nBin_; j++)
1194 const word jn(
'(' + Foam::name(j) +
')');
1195 const word f(
"forces" + jn + binForceTypes);
1196 const word m(
"moments" + jn + binForceTypes);
1197 file(
i) << tab << f << tab << m;
1202 for (label j = 0; j <
nBin_; j++)
1204 const word jn(
'(' + Foam::name(j) +
')');
1205 const word f(
"localForces" + jn + binForceTypes);
1206 const word m(
"localMoments" + jn + binForceTypes);
1207 file(
i) << tab << f << tab << m;
1216 FatalErrorInFunction
1217 <<
"Unhandled file index: " <<
i
1218 << abort(FatalError);
1235 if (!obr_.foundObject<volVectorField>(
fDName_))
1237 FatalErrorInFunction
1238 <<
"Could not find " <<
fDName_ <<
" in database."
1239 << exit(FatalError);
1246 !obr_.foundObject<volVectorField>(
UName_)
1247 || !obr_.foundObject<volScalarField>(
pName_)
1250 FatalErrorInFunction
1252 << exit(FatalError);
1258 && !obr_.foundObject<volScalarField>(
rhoName_)
1261 FatalErrorInFunction
1263 << exit(FatalError);
1271Foam::tmp<Foam::volSymmTensorField>
1274 typedef compressible::turbulenceModel cmpTurbModel;
1275 typedef incompressible::turbulenceModel icoTurbModel;
1277 if (obr_.foundObject<cmpTurbModel>(cmpTurbModel::propertiesName))
1279 const cmpTurbModel& turb =
1280 obr_.lookupObject<cmpTurbModel>(cmpTurbModel::propertiesName);
1281 return turb.devRhoReff();
1283 else if (obr_.foundObject<icoTurbModel>(icoTurbModel::propertiesName))
1285 const incompressible::turbulenceModel& turb =
1286 obr_.lookupObject<icoTurbModel>(icoTurbModel::propertiesName);
1287 return rho() * turb.devReff();
1289 else if (obr_.foundObject<fluidThermo>(fluidThermo::dictName))
1291 const fluidThermo&
thermo =
1292 obr_.lookupObject<fluidThermo>(fluidThermo::dictName);
1293 const volVectorField&
U = obr_.lookupObject<volVectorField>(
UName_);
1294 return -
thermo.mu() * dev(twoSymm(fvc::grad(
U)));
1298 obr_.foundObject<transportModel>(
"transportProperties")
1301 const transportModel& laminarT =
1302 obr_.lookupObject<transportModel>(
"transportProperties");
1303 const volVectorField&
U = obr_.lookupObject<volVectorField>(
UName_);
1304 return -
rho() * laminarT.nu() * dev(twoSymm(fvc::grad(
U)));
1306 else if (obr_.foundObject<dictionary>(
"transportProperties"))
1309 obr_.lookupObject<dictionary>(
"transportProperties");
1311 const volVectorField&
U = obr_.lookupObject<volVectorField>(
UName_);
1312 return -
rho() *
nu * dev(twoSymm(fvc::grad(
U)));
1316 FatalErrorInFunction
1317 <<
"No valid model for viscous stress calculation"
1318 << exit(FatalError);
1319 return volSymmTensorField::null();
1326 if (obr_.foundObject<fluidThermo>(basicThermo::dictName))
1328 const fluidThermo&
thermo =
1329 obr_.lookupObject<fluidThermo>(basicThermo::dictName);
1334 obr_.foundObject<transportModel>(
"transportProperties")
1337 const transportModel& laminarT =
1338 obr_.lookupObject<transportModel>(
"transportProperties");
1339 return rho() * laminarT.nu();
1341 else if (obr_.foundObject<dictionary>(
"transportProperties"))
1344 obr_.lookupObject<dictionary>(
"transportProperties");
1345 dimensionedScalar
nu
1355 FatalErrorInFunction
1356 <<
"No valid model for dynamic viscosity calculation"
1357 << exit(FatalError);
1358 return volScalarField::null();
1367 return tmp<volScalarField>
1374 mesh_.time().timeName(),
1378 dimensionedScalar(
"rho", dimDensity,
rhoRef_)
1384 return (obr_.lookupObject<volScalarField>(
rhoName_));
1392 if (
p.dimensions() == dimPressure)
1400 FatalErrorInFunction
1401 <<
"Dynamic pressure is expected but kinematic is provided."
1402 << exit(FatalError);
1412 const vectorField& Md,
1413 const vectorField& fN,
1414 const vectorField& fT,
1415 const vectorField& fP,
1416 const vectorField& d
1424 moment_[0][0] += sum(Md ^ fN);
1425 moment_[1][0] += sum(Md ^ fT);
1426 moment_[2][0] += sum(Md ^ fP);
1433 label bini = min(max(floor(dd[
i] /
binDx_), 0),
force_[0].size() - 1);
1447 Log << type() <<
" " << name() <<
" write:" << nl
1448 <<
" sum of forces:" << nl
1449 <<
" pressure : " << sum(
force_[0]) << nl
1450 <<
" viscous : " << sum(
force_[1]) << nl
1451 <<
" porous : " << sum(
force_[2]) << nl
1452 <<
" sum of moments:" << nl
1453 <<
" pressure : " << sum(
moment_[0]) << nl
1454 <<
" viscous : " << sum(
moment_[1]) << nl
1455 <<
" porous : " << sum(
moment_[2])
1458 file(
MAIN_FILE) << tab << setw(1) <<
'('
1459 << sum(
force_[0]) << setw(1) <<
' '
1460 << sum(
force_[1]) << setw(1) <<
' '
1461 << sum(
force_[2]) << setw(3) <<
") ("
1462 << sum(
moment_[0]) << setw(1) <<
' '
1463 << sum(
moment_[1]) << setw(1) <<
' '
1464 << sum(
moment_[2]) << setw(1) <<
')'
1476 file(
MAIN_FILE) << tab << setw(1) <<
'('
1477 << sum(localForceN) << setw(1) <<
' '
1478 << sum(localForceT) << setw(1) <<
' '
1479 << sum(localForceP) << setw(3) <<
") ("
1480 << sum(localMomentN) << setw(1) <<
' '
1481 << sum(localMomentT) << setw(1) <<
' '
1482 << sum(localMomentP) << setw(1) <<
')'
1495 List<Field<vector >> f(
force_);
1496 List<Field<vector >> m(
moment_);
1500 for (label
i = 1;
i < f[0].size();
i++)
1502 f[0][
i] += f[0][
i - 1];
1503 f[1][
i] += f[1][
i - 1];
1504 f[2][
i] += f[2][
i - 1];
1505 m[0][
i] += m[0][
i - 1];
1506 m[1][
i] += m[1][
i - 1];
1507 m[2][
i] += m[2][
i - 1];
1514 << tab << setw(1) <<
'('
1515 << f[0][
i] << setw(1) <<
' '
1516 << f[1][
i] << setw(1) <<
' '
1517 << f[2][
i] << setw(3) <<
") ("
1518 << m[0][
i] << setw(1) <<
' '
1519 << m[1][
i] << setw(1) <<
' '
1520 << m[2][
i] << setw(1) <<
')';
1525 List<Field<vector >> lf(3);
1526 List<Field<vector >> lm(3);
1536 for (label
i = 1;
i < lf[0].size();
i++)
1538 lf[0][
i] += lf[0][
i - 1];
1539 lf[1][
i] += lf[1][
i - 1];
1540 lf[2][
i] += lf[2][
i - 1];
1541 lm[0][
i] += lm[0][
i - 1];
1542 lm[1][
i] += lm[1][
i - 1];
1543 lm[2][
i] += lm[2][
i - 1];
1549 << tab << setw(1) <<
'('
1550 << lf[0][
i] << setw(1) <<
' '
1551 << lf[1][
i] << setw(1) <<
' '
1552 << lf[2][
i] << setw(3) <<
") ("
1553 << lm[0][
i] << setw(1) <<
' '
1554 << lm[1][
i] << setw(1) <<
' '
1555 << lm[2][
i] << setw(1) <<
')';
1568 const dictionary& dict
1571 fvMeshFunctionObject(name,
runTime, dict),
1572 logFiles(obr_, name),
1602 const objectRegistry& obr,
1603 const dictionary& dict
1606 fvMeshFunctionObject(name, obr, dict),
1607 logFiles(obr_, name),
1644 fvMeshFunctionObject::read(dict);
1646 Log << type() <<
" " << name() <<
":" << nl;
1648 const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
1649 patchSet_ = pbm.patchSet(wordReList(dict.lookup(
"patches")));
1654 fDName_ = dict.lookupOrDefault<word>(
"fD",
"fD");
1659 pName_ = dict.lookupOrDefault<word>(
"p",
"p");
1660 UName_ = dict.lookupOrDefault<word>(
"U",
"U");
1661 rhoName_ = dict.lookupOrDefault<word>(
"rho",
"rho");
1666 dict.lookup(
"rhoInf") >>
rhoRef_;
1670 pRef_ = dict.lookupOrDefault<scalar>(
"pRef", 0.0);
1677 if (!dict.readIfPresent<point>(
"CofR",
coordSys_.origin()))
1679 coordSys_ = coordinateSystem(obr_, dict);
1683 dict.readIfPresent(
"porosity",
porosity_);
1687 Log <<
" Including porosity effects" << endl;
1691 Log <<
" Not including porosity effects" << endl;
1694 if (dict.found(
"binData"))
1696 const dictionary& binDict(dict.subDict(
"binData"));
1697 binDict.lookup(
"nBin") >>
nBin_;
1701 FatalIOErrorInFunction(dict)
1702 <<
"Number of bins (nBin) must be zero or greater"
1703 << exit(FatalIOError);
1717 binDict.lookup(
"direction") >>
binDir_;
1720 scalar binMax = -GREAT;
1721 forAllConstIter(labelHashSet,
patchSet_, iter)
1723 label patchi = iter.key();
1724 const polyPatch& pp = pbm[patchi];
1725 scalarField d(pp.faceCentres() &
binDir_);
1727 binMax = max(max(d), binMax);
1730 reduce(
binMin_, minOp<scalar>());
1731 reduce(binMax, maxOp<scalar>());
1780 const volVectorField& fD = obr_.lookupObject<volVectorField>(
fDName_);
1781 const surfaceVectorField::Boundary& Sfb =
1782 mesh_.Sf().boundaryField();
1783 forAllConstIter(labelHashSet,
patchSet_, iter)
1785 label patchi = iter.key();
1788 mesh_.C().boundaryField()[patchi] -
coordSys_.origin()
1790 scalarField sA(mag(Sfb[patchi]));
1796 Sfb[patchi] & fD.boundaryField()[patchi]
1800 vectorField fT(sA * fD.boundaryField()[patchi] - fN);
1802 vectorField fP(Md.size(), Zero);
1803 applyBins(Md, fN, fT, fP, mesh_.C().boundaryField()[patchi]);
1808 const volScalarField&
p = obr_.lookupObject<volScalarField>(
pName_);
1809 const surfaceVectorField::Boundary& Sfb =
1810 mesh_.Sf().boundaryField();
1811 tmp<volSymmTensorField> tdevRhoReff =
devRhoReff();
1812 const volSymmTensorField::Boundary& devRhoReffb
1813 = tdevRhoReff().boundaryField();
1816 forAllConstIter(labelHashSet,
patchSet_, iter)
1818 label patchi = iter.key();
1821 mesh_.C().boundaryField()[patchi] -
coordSys_.origin()
1825 rho(
p) * Sfb[patchi] * (
p.boundaryField()[patchi] - pRef)
1827 vectorField fT(Sfb[patchi] & devRhoReffb[patchi]);
1828 vectorField fP(Md.size(), Zero);
1829 applyBins(Md, fN, fT, fP, mesh_.C().boundaryField()[patchi]);
1835 const volVectorField&
U = obr_.lookupObject<volVectorField>(
UName_);
1836 const volScalarField
rho(this->
rho());
1837 const volScalarField
mu(this->
mu());
1838 const HashTable<const porosityModel*> models =
1839 obr_.lookupClass<porosityModel>();
1844 <<
"Porosity effects requested, but no porosity models found "
1845 <<
"in the database"
1849 forAllConstIter(HashTable<const porosityModel*>, models, iter)
1852 porosityModel& pm =
const_cast<porosityModel&
>(* iter());
1853 vectorField fPTot(pm.force(
U,
rho,
mu));
1854 const labelList& cellZoneIDs = pm.cellZoneIDs();
1857 label zoneI = cellZoneIDs[
i];
1858 const cellZone& cZone = mesh_.cellZones()[zoneI];
1859 const vectorField d(mesh_.C(), cZone);
1860 const vectorField fP(fPTot, cZone);
1861 const vectorField Md(d -
coordSys_.origin());
1862 const vectorField fDummy(Md.size(), Zero);
1868 Pstream::listCombineGather(
force_, plusEqOp<vectorField>());
1869 Pstream::listCombineGather(
moment_, plusEqOp<vectorField>());
1870 Pstream::listCombineScatter(
force_);
1871 Pstream::listCombineScatter(
moment_);
1912 if (Pstream::master())
forAll(example_CG.gList, solutionI)
List< Field< vector > > moment_
virtual vector forcePressure() const
virtual vector forceEff() const
void writeBinnedForceMoment(const List< Field< vector > > &fm, autoPtr< OFstream > &osPtr) const
void writeIntegratedForceMoment(const string &descriptor, const vectorField &fm0, const vectorField &fm1, const vectorField &fm2, autoPtr< OFstream > &osPtr) const
virtual bool read(const dictionary &)
virtual void writeFileHeader(const label i)
virtual vector forcePorous() const
tmp< volScalarField > rho() const
tmp< volScalarField > mu() const
void applyBins(const vectorField &Md, const vectorField &fN, const vectorField &fT, const vectorField &fP, const vectorField &d)
wordList createFileNames(const dictionary &dict) const
void addToFields(const label patchi, const vectorField &Md, const vectorField &fN, const vectorField &fT, const vectorField &fP)
virtual vector forceTau() const
word fieldName(const word &name) const
virtual vector momentEff() const
void writeBinHeader(const word &header, Ostream &os) const
List< Field< vector > > force_
virtual void calcForcesMoment()
void writeIntegratedHeader(const word &header, Ostream &os) const
tmp< volSymmTensorField > devRhoReff() const
Switch directForceDensity_
coordinateSystem coordSys_
ITHACAforces(const ITHACAforces &)
T max(Eigen::SparseMatrix< T > &mat, label &ind_row, label &ind_col)
Find the maximum of a sparse Matrix (Useful for DEIM)
T min(Eigen::SparseMatrix< T > &mat, label &ind_row, label &ind_col)
Find the minimum of a sparse Matrix (Useful for DEIM)
defineTypeNameAndDebug(ITHACAforces, 0)
addToRunTimeSelectionTable(functionObject, ITHACAforces, dictionary)
const char * NamedEnum< Foam::incompressible::turbulentHeatFluxTemperatureFvPatchScalarField::heatSourceType, 2 >::names[]
IOdictionary transportProperties(IOobject("transportProperties", runTime.constant(), mesh, IOobject::MUST_READ_IF_MODIFIED, IOobject::NO_WRITE))