forces.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2015-2023 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "forces.H"
30 #include "fvcGrad.H"
31 #include "porosityModel.H"
34 #include "cartesianCS.H"
36 
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38 
39 namespace Foam
40 {
41 namespace functionObjects
42 {
43  defineTypeNameAndDebug(forces, 0);
44  addToRunTimeSelectionTable(functionObject, forces, dictionary);
45 }
46 }
47 
48 
49 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
50 
52 (
53  const dictionary& dict,
54  const word& e3Name,
55  const word& e1Name
56 )
57 {
58  point origin(Zero);
59 
60  // With objectRegistry for access to indirect (global) coordinate systems
61  coordSysPtr_ = coordinateSystem::NewIfPresent(obr_, dict);
62 
63  if (coordSysPtr_)
64  {
65  // Report ...
66  }
67  else if (dict.readIfPresent("CofR", origin))
68  {
69  const vector e3
70  (
71  e3Name.empty() ? vector(0, 0, 1) : dict.get<vector>(e3Name)
72  );
73  const vector e1
74  (
75  e1Name.empty() ? vector(1, 0, 0) : dict.get<vector>(e1Name)
76  );
77 
78  coordSysPtr_.reset(new coordSystem::cartesian(origin, e3, e1));
79  }
80  else
81  {
82  // No 'coordinateSystem' or 'CofR'
83  // - enforce a cartesian system
84 
86  }
87 }
88 
89 
91 {
92  auto* forcePtr = mesh_.getObjectPtr<volVectorField>(scopedName("force"));
93 
94  if (!forcePtr)
95  {
96  forcePtr = new volVectorField
97  (
98  IOobject
99  (
100  scopedName("force"),
101  time_.timeName(),
102  mesh_,
106  ),
107  mesh_,
109  );
110 
111  mesh_.objectRegistry::store(forcePtr);
112  }
113 
114  return *forcePtr;
115 }
116 
117 
119 {
120  auto* momentPtr = mesh_.getObjectPtr<volVectorField>(scopedName("moment"));
121 
122  if (!momentPtr)
123  {
124  momentPtr = new volVectorField
125  (
126  IOobject
127  (
128  scopedName("moment"),
129  time_.timeName(),
130  mesh_,
134  ),
135  mesh_,
137  );
138 
139  mesh_.objectRegistry::store(momentPtr);
140  }
141 
142  return *momentPtr;
143 }
144 
145 
147 {
148  if (initialised_)
149  {
150  return;
151  }
152 
153  if (directForceDensity_)
154  {
155  if (!foundObject<volVectorField>(fDName_))
156  {
158  << "Could not find " << fDName_ << " in database"
159  << exit(FatalError);
160  }
161  }
162  else
163  {
164  if
165  (
166  !foundObject<volVectorField>(UName_)
167  || !foundObject<volScalarField>(pName_)
168  )
169  {
171  << "Could not find U: " << UName_
172  << " or p:" << pName_ << " in database"
173  << exit(FatalError);
174  }
175 
176  if (rhoName_ != "rhoInf" && !foundObject<volScalarField>(rhoName_))
177  {
179  << "Could not find rho:" << rhoName_ << " in database"
180  << exit(FatalError);
181  }
182  }
183 
184  initialised_ = true;
185 }
186 
187 
189 {
190  sumPatchForcesP_ = Zero;
191  sumPatchForcesV_ = Zero;
192  sumPatchMomentsP_ = Zero;
193  sumPatchMomentsV_ = Zero;
194 
195  sumInternalForces_ = Zero;
196  sumInternalMoments_ = Zero;
197 
198  auto& force = this->force();
199  auto& moment = this->moment();
200 
201  if (porosity_)
202  {
203  force == dimensionedVector(force.dimensions(), Zero);
204  moment == dimensionedVector(moment.dimensions(), Zero);
205  }
206  else
207  {
208  constexpr bool updateAccessTime = false;
209  for (const label patchi : patchIDs_)
210  {
211  force.boundaryFieldRef(updateAccessTime)[patchi] = Zero;
212  moment.boundaryFieldRef(updateAccessTime)[patchi] = Zero;
213  }
214  }
215 }
216 
217 
220 (
221  const tensorField& gradUp,
222  const label patchi
223 ) const
224 {
225  typedef incompressible::turbulenceModel icoTurbModel;
226  typedef compressible::turbulenceModel cmpTurbModel;
227 
228  if (foundObject<icoTurbModel>(icoTurbModel::propertiesName))
229  {
230  const auto& turb =
231  lookupObject<icoTurbModel>(icoTurbModel::propertiesName);
232 
233  return -rho(patchi)*turb.nuEff(patchi)*devTwoSymm(gradUp);
234  }
235  else if (foundObject<cmpTurbModel>(cmpTurbModel::propertiesName))
236  {
237  const auto& turb =
238  lookupObject<cmpTurbModel>(cmpTurbModel::propertiesName);
239 
240  return -turb.muEff(patchi)*devTwoSymm(gradUp);
241  }
242  else if (foundObject<fluidThermo>(fluidThermo::dictName))
243  {
244  const auto& thermo = lookupObject<fluidThermo>(fluidThermo::dictName);
245 
246  return -thermo.mu(patchi)*devTwoSymm(gradUp);
247  }
248  else if (foundObject<transportModel>("transportProperties"))
249  {
250  const auto& laminarT =
251  lookupObject<transportModel>("transportProperties");
252 
253  return -rho(patchi)*laminarT.nu(patchi)*devTwoSymm(gradUp);
254  }
255  else if (foundObject<dictionary>("transportProperties"))
256  {
257  const auto& transportProperties =
258  lookupObject<dictionary>("transportProperties");
259 
261 
262  return -rho(patchi)*nu.value()*devTwoSymm(gradUp);
263  }
264  else
265  {
267  << "No valid model for viscous stress calculation"
269 
270  return volSymmTensorField::null();
271  }
272 }
273 
274 
276 {
277  if (foundObject<fluidThermo>(basicThermo::dictName))
278  {
279  const auto& thermo = lookupObject<fluidThermo>(basicThermo::dictName);
280 
281  return thermo.mu();
282  }
283  else if (foundObject<transportModel>("transportProperties"))
284  {
285  const auto& laminarT =
286  lookupObject<transportModel>("transportProperties");
287 
288  return rho()*laminarT.nu();
289  }
290  else if (foundObject<dictionary>("transportProperties"))
291  {
292  const auto& transportProperties =
293  lookupObject<dictionary>("transportProperties");
294 
296 
297  return rho()*nu;
298  }
299  else
300  {
302  << "No valid model for dynamic viscosity calculation"
304 
305  return volScalarField::null();
306  }
307 }
308 
309 
311 {
312  if (rhoName_ == "rhoInf")
313  {
315  (
316  IOobject
317  (
318  "rho",
319  mesh_.time().timeName(),
320  mesh_
321  ),
322  mesh_,
323  dimensionedScalar(dimDensity, rhoRef_)
324  );
325  }
326 
327  return (lookupObject<volScalarField>(rhoName_));
328 }
329 
330 
332 Foam::functionObjects::forces::rho(const label patchi) const
333 {
334  if (rhoName_ == "rhoInf")
335  {
336  return tmp<scalarField>::New
337  (
338  mesh_.boundary()[patchi].size(),
339  rhoRef_
340  );
341  }
342 
343  const auto& rho = lookupObject<volScalarField>(rhoName_);
344  return rho.boundaryField()[patchi];
345 }
346 
347 
348 Foam::scalar Foam::functionObjects::forces::rho(const volScalarField& p) const
349 {
350  if (p.dimensions() == dimPressure)
351  {
352  return 1;
353  }
354 
355  if (rhoName_ != "rhoInf")
356  {
358  << "Dynamic pressure is expected but kinematic is provided."
359  << exit(FatalError);
360  }
361 
362  return rhoRef_;
363 }
364 
365 
367 (
368  const label patchi,
369  const vectorField& Md,
370  const vectorField& fP,
371  const vectorField& fV
372 )
373 {
374  constexpr bool updateAccessTime = false;
375 
376  sumPatchForcesP_ += sum(fP);
377  sumPatchForcesV_ += sum(fV);
378  force().boundaryFieldRef(updateAccessTime)[patchi] += fP + fV;
379 
380  const vectorField mP(Md^fP);
381  const vectorField mV(Md^fV);
382 
383  sumPatchMomentsP_ += sum(mP);
384  sumPatchMomentsV_ += sum(mV);
385  moment().boundaryFieldRef(updateAccessTime)[patchi] += mP + mV;
386 }
387 
388 
390 (
391  const labelList& cellIDs,
392  const vectorField& Md,
393  const vectorField& f
394 )
395 {
396  auto& force = this->force();
397  auto& moment = this->moment();
398 
399  forAll(cellIDs, i)
400  {
401  const label celli = cellIDs[i];
402 
403  sumInternalForces_ += f[i];
404  force[celli] += f[i];
405 
406  const vector m(Md[i]^f[i]);
407  sumInternalMoments_ += m;
408  moment[celli] = m;
409  }
410 }
411 
412 
414 {
415  if (!forceFilePtr_)
416  {
417  forceFilePtr_ = newFileAtStartTime("force");
418  writeIntegratedDataFileHeader("Force", forceFilePtr_());
419  }
420 
421  if (!momentFilePtr_)
422  {
423  momentFilePtr_ = newFileAtStartTime("moment");
424  writeIntegratedDataFileHeader("Moment", momentFilePtr_());
425  }
426 }
427 
428 
430 (
431  const word& header,
432  OFstream& os
433 ) const
434 {
435  const auto& coordSys = coordSysPtr_();
436  const auto vecDesc = [](const word& root)->string
437  {
438  return root + "_x " + root + "_y " + root + "_z";
439  };
440  writeHeader(os, header);
441  writeHeaderValue(os, "CofR", coordSys.origin());
442  writeHeader(os, "");
443  writeCommented(os, "Time");
444  writeTabbed(os, vecDesc("total"));
445  writeTabbed(os, vecDesc("pressure"));
446  writeTabbed(os, vecDesc("viscous"));
447 
448  if (porosity_)
449  {
450  writeTabbed(os, vecDesc("porous"));
451  }
452 
453  os << endl;
454 }
455 
456 
458 {
459  const auto& coordSys = coordSysPtr_();
460 
461  writeIntegratedDataFile
462  (
463  coordSys.localVector(sumPatchForcesP_),
464  coordSys.localVector(sumPatchForcesV_),
465  coordSys.localVector(sumInternalForces_),
466  forceFilePtr_()
467  );
468 
469  writeIntegratedDataFile
470  (
471  coordSys.localVector(sumPatchMomentsP_),
472  coordSys.localVector(sumPatchMomentsV_),
473  coordSys.localVector(sumInternalMoments_),
474  momentFilePtr_()
475  );
476 }
477 
478 
480 (
481  const vector& pres,
482  const vector& vis,
483  const vector& internal,
484  OFstream& os
485 ) const
486 {
487  writeCurrentTime(os);
488 
489  writeValue(os, pres + vis + internal);
490  writeValue(os, pres);
491  writeValue(os, vis);
492 
493  if (porosity_)
494  {
495  writeValue(os, internal);
496  }
497 
498  os << endl;
499 }
500 
501 
503 (
504  const string& descriptor,
505  const vector& pres,
506  const vector& vis,
507  const vector& internal
508 ) const
509 {
510  if (!log)
511  {
512  return;
513  }
514 
515  Log << " Sum of " << descriptor.c_str() << nl
516  << " Total : " << (pres + vis + internal) << nl
517  << " Pressure : " << pres << nl
518  << " Viscous : " << vis << nl;
519 
520  if (porosity_)
521  {
522  Log << " Porous : " << internal << nl;
523  }
524 }
525 
526 
527 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
528 
530 (
531  const word& name,
532  const Time& runTime,
533  const dictionary& dict,
534  bool readFields
535 )
536 :
537  fvMeshFunctionObject(name, runTime, dict),
538  writeFile(mesh_, name),
539  sumPatchForcesP_(Zero),
540  sumPatchForcesV_(Zero),
541  sumPatchMomentsP_(Zero),
542  sumPatchMomentsV_(Zero),
543  sumInternalForces_(Zero),
544  sumInternalMoments_(Zero),
545  forceFilePtr_(),
546  momentFilePtr_(),
547  coordSysPtr_(nullptr),
548  rhoRef_(VGREAT),
549  pRef_(0),
550  pName_("p"),
551  UName_("U"),
552  rhoName_("rho"),
553  fDName_("fD"),
554  directForceDensity_(false),
555  porosity_(false),
556  writeFields_(false),
557  initialised_(false)
558 {
559  if (readFields)
560  {
561  read(dict);
563  Log << endl;
564  }
565 }
566 
567 
569 (
570  const word& name,
571  const objectRegistry& obr,
572  const dictionary& dict,
573  bool readFields
574 )
575 :
576  fvMeshFunctionObject(name, obr, dict),
577  writeFile(mesh_, name),
578  sumPatchForcesP_(Zero),
579  sumPatchForcesV_(Zero),
580  sumPatchMomentsP_(Zero),
581  sumPatchMomentsV_(Zero),
582  sumInternalForces_(Zero),
583  sumInternalMoments_(Zero),
584  forceFilePtr_(),
585  momentFilePtr_(),
586  coordSysPtr_(nullptr),
587  rhoRef_(VGREAT),
588  pRef_(0),
589  pName_("p"),
590  UName_("U"),
591  rhoName_("rho"),
592  fDName_("fD"),
593  directForceDensity_(false),
594  porosity_(false),
595  writeFields_(false),
596  initialised_(false)
597 {
598  if (readFields)
599  {
600  read(dict);
602  Log << endl;
603  }
604 }
605 
606 
607 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
608 
610 {
611  const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
612 
614  {
615  return false;
616  }
617 
618  initialised_ = false;
619 
620  Info<< type() << ' ' << name() << ':' << endl;
621 
622  // Can also use pbm.indices(), but no warnings...
623  patchIDs_ = pbm.patchSet(dict.get<wordRes>("patches")).sortedToc();
624 
625  dict.readIfPresent("directForceDensity", directForceDensity_);
626  if (directForceDensity_)
627  {
628  // Optional name entry for fD
629  if (dict.readIfPresent<word>("fD", fDName_))
630  {
631  Info<< " fD: " << fDName_ << endl;
632  }
633  }
634  else
635  {
636  // Optional field name entries
637  if (dict.readIfPresent<word>("p", pName_))
638  {
639  Info<< " p: " << pName_ << endl;
640  }
641  if (dict.readIfPresent<word>("U", UName_))
642  {
643  Info<< " U: " << UName_ << endl;
644  }
645  if (dict.readIfPresent<word>("rho", rhoName_))
646  {
647  Info<< " rho: " << rhoName_ << endl;
648  }
649 
650  // Reference density needed for incompressible calculations
651  if (rhoName_ == "rhoInf")
652  {
653  rhoRef_ = dict.getCheck<scalar>("rhoInf", scalarMinMax::ge(SMALL));
654  Info<< " Freestream density (rhoInf) set to " << rhoRef_ << endl;
655  }
656 
657  // Reference pressure, 0 by default
658  if (dict.readIfPresent<scalar>("pRef", pRef_))
659  {
660  Info<< " Reference pressure (pRef) set to " << pRef_ << endl;
661  }
662  }
663 
664  dict.readIfPresent("porosity", porosity_);
665  if (porosity_)
666  {
667  Info<< " Including porosity effects" << endl;
668  }
669  else
670  {
671  Info<< " Not including porosity effects" << endl;
672  }
673 
674  writeFields_ = dict.getOrDefault("writeFields", false);
675  if (writeFields_)
676  {
677  Info<< " Fields will be written" << endl;
678  }
679 
680 
681  return true;
682 }
683 
684 
686 {
687  initialise();
688 
689  reset();
690 
691  const point& origin = coordSysPtr_->origin();
692 
693  if (directForceDensity_)
694  {
695  const auto& fD = lookupObject<volVectorField>(fDName_);
696  const auto& fDb = fD.boundaryField();
697 
698  const auto& Sfb = mesh_.Sf().boundaryField();
699  const auto& magSfb = mesh_.magSf().boundaryField();
700  const auto& Cb = mesh_.C().boundaryField();
701 
702  for (const label patchi : patchIDs_)
703  {
704  const vectorField Md(Cb[patchi] - origin);
705 
706  // Pressure force = surfaceUnitNormal*(surfaceNormal & forceDensity)
707  const vectorField fP
708  (
709  Sfb[patchi]/magSfb[patchi]
710  *(
711  Sfb[patchi] & fDb[patchi]
712  )
713  );
714 
715  // Viscous force (total force minus pressure fP)
716  const vectorField fV(magSfb[patchi]*fDb[patchi] - fP);
717 
718  addToPatchFields(patchi, Md, fP, fV);
719  }
720  }
721  else
722  {
723  const auto& p = lookupObject<volScalarField>(pName_);
724  const auto& pb = p.boundaryField();
725 
726  const auto& Sfb = mesh_.Sf().boundaryField();
727  const auto& Cb = mesh_.C().boundaryField();
728 
729  const auto& U = lookupObject<volVectorField>(UName_);
730  tmp<volTensorField> tgradU = fvc::grad(U);
731  const volTensorField& gradU = tgradU();
732  const auto& gradUb = gradU.boundaryField();
733 
734  // Scale pRef by density for incompressible simulations
735  const scalar rhoRef = rho(p);
736  const scalar pRef = pRef_/rhoRef;
737 
738  for (const label patchi : patchIDs_)
739  {
740  const vectorField Md(Cb[patchi] - origin);
741 
742  const vectorField fP(rhoRef*Sfb[patchi]*(pb[patchi] - pRef));
743 
744  const vectorField fV
745  (
746  Sfb[patchi] & devRhoReff(gradUb[patchi], patchi)
747  );
748 
749  addToPatchFields(patchi, Md, fP, fV);
750  }
751  }
752 
753  if (porosity_)
754  {
755  const auto& U = lookupObject<volVectorField>(UName_);
756  const volScalarField rho(this->rho());
757  const volScalarField mu(this->mu());
758 
759  const UPtrList<const porosityModel> models
760  (
761  obr_.csorted<porosityModel>()
762  );
763 
764  if (models.empty())
765  {
767  << "Porosity effects requested, "
768  << "but no porosity models found in the database"
769  << endl;
770  }
771 
772  for (const porosityModel& mdl : models)
773  {
774  // Non-const access required if mesh is changing
775  auto& pm = const_cast<porosityModel&>(mdl);
776 
777  const vectorField fPTot(pm.force(U, rho, mu));
778 
779  const labelList& cellZoneIDs = pm.cellZoneIDs();
780 
781  for (const label zonei : cellZoneIDs)
782  {
783  const cellZone& cZone = mesh_.cellZones()[zonei];
784 
785  const vectorField d(mesh_.C(), cZone);
786  const vectorField fP(fPTot, cZone);
787  const vectorField Md(d - origin);
788 
789  addToInternalField(cZone, Md, fP);
790  }
791  }
792  }
793 
794  reduce(sumPatchForcesP_, sumOp<vector>());
795  reduce(sumPatchForcesV_, sumOp<vector>());
796  reduce(sumPatchMomentsP_, sumOp<vector>());
797  reduce(sumPatchMomentsV_, sumOp<vector>());
798  reduce(sumInternalForces_, sumOp<vector>());
799  reduce(sumInternalMoments_, sumOp<vector>());
800 }
801 
804 {
805  return sumPatchForcesP_ + sumPatchForcesV_ + sumInternalForces_;
806 }
807 
810 {
811  return sumPatchMomentsP_ + sumPatchMomentsV_ + sumInternalMoments_;
812 }
813 
814 
816 {
817  calcForcesMoments();
818 
819  Log << type() << " " << name() << " write:" << nl;
820 
821  const auto& coordSys = coordSysPtr_();
822 
823  const auto localFp(coordSys.localVector(sumPatchForcesP_));
824  const auto localFv(coordSys.localVector(sumPatchForcesV_));
825  const auto localFi(coordSys.localVector(sumInternalForces_));
826 
827  logIntegratedData("forces", localFp, localFv, localFi);
828 
829  const auto localMp(coordSys.localVector(sumPatchMomentsP_));
830  const auto localMv(coordSys.localVector(sumPatchMomentsV_));
831  const auto localMi(coordSys.localVector(sumInternalMoments_));
832 
833  logIntegratedData("moments", localMp, localMv, localMi);
834 
835  setResult("pressureForce", localFp);
836  setResult("viscousForce", localFv);
837  setResult("internalForce", localFi);
838  setResult("pressureMoment", localMp);
839  setResult("viscousMoment", localMv);
840  setResult("internalMoment", localMi);
841 
842  return true;
843 }
844 
845 
847 {
848  if (writeToFile())
849  {
850  Log << " writing force and moment files." << endl;
851 
852  createIntegratedDataFiles();
853  writeIntegratedDataFiles();
854  }
855 
856  if (writeFields_)
857  {
858  Log << " writing force and moment fields." << endl;
859 
860  force().write();
861  moment().write();
862  }
863 
864  Log << endl;
865 
866  return true;
867 }
868 
869 
870 // ************************************************************************* //
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
virtual vector momentEff() const
Return the total moment.
Definition: forces.C:802
word dictName() const
The local dictionary name (final part of scoped name)
Definition: dictionaryI.H:53
const polyBoundaryMesh & pbm
dictionary dict
tmp< GeometricField< typename outerProduct< vector, Type >::type, fvPatchField, volMesh >> grad(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Definition: fvcGrad.C:47
defineTypeNameAndDebug(ObukhovLength, 0)
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1)
static bool initialised_(false)
static void writeHeader(Ostream &os, const word &fieldName)
dimensionedScalar log(const dimensionedScalar &ds)
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
GeometricField< tensor, fvPatchField, volMesh > volTensorField
Definition: volFieldsFwd.H:86
Output to file stream, using an OSstream.
Definition: OFstream.H:49
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
const dimensionSet dimViscosity
compressible::turbulenceModel & turb
dimensioned< vector > dimensionedVector
Dimensioned vector obtained from generic dimensioned type.
engineTime & runTime
ThermalDiffusivity< CompressibleTurbulenceModel< fluidThermo > > turbulenceModel
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
volVectorField & force()
Return access to the force field.
Definition: forces.C:83
An indexed form of CGAL::Triangulation_cell_base_3<K> used to keep track of the Delaunay cells (tets)...
Definition: indexedCell.H:62
virtual vector forceEff() const
Return the total force.
Definition: forces.C:796
IncompressibleTurbulenceModel< transportModel > turbulenceModel
Ignore writing from objectRegistry::writeObject()
GeometricField< vector, fvPatchField, volMesh > volVectorField
Definition: volFieldsFwd.H:82
void addToPatchFields(const label patchi, const vectorField &Md, const vectorField &fP, const vectorField &fV)
Add patch contributions to force and moment fields.
Definition: forces.C:360
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:69
virtual bool read(const dictionary &dict)
Read the dictionary.
Definition: forces.C:602
void writeIntegratedDataFiles()
Write integrated data to files.
Definition: forces.C:450
Macros for easy insertion into run-time selection tables.
tmp< symmTensorField > devRhoReff(const tensorField &gradUp, const label patchi) const
Return the effective stress (viscous + turbulent) for patch.
Definition: forces.C:213
void writeIntegratedDataFile(const vector &pres, const vector &vis, const vector &internal, OFstream &os) const
Write integrated data to a file.
Definition: forces.C:473
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
A Cartesian coordinate system.
Definition: cartesianCS.H:65
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:81
psiReactionThermo & thermo
Definition: createFields.H:28
virtual bool execute()
Execute the function object.
Definition: forces.C:808
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:799
virtual void calcForcesMoments()
Calculate forces and moments.
Definition: forces.C:678
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
void readFields(const typename GeoFieldType::Mesh &mesh, const IOobjectList &objects, const NameMatchPredicate &selectedFields, DynamicList< regIOobject *> &storedObjects)
Read the selected GeometricFields of the templated type and store on the objectRegistry.
Calculate the gradient of the given field.
A class for handling words, derived from Foam::string.
Definition: word.H:63
tmp< volScalarField > mu() const
Return dynamic viscosity field.
Definition: forces.C:268
static MinMax< scalar > ge(const scalar &minVal)
A semi-infinite range from minVal to the type max.
Definition: MinMaxI.H:24
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
Definition: tmp.H:206
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
IOdictionary transportProperties(IOobject("transportProperties", runTime.constant(), mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Vector< scalar > vector
Definition: vector.H:57
void addToInternalField(const labelList &cellIDs, const vectorField &Md, const vectorField &f)
Add cell contributions to force and moment fields, and include porosity effects.
Definition: forces.C:383
tmp< volScalarField > rho() const
Return rho if specified otherwise rhoRef.
Definition: forces.C:303
const dimensionSet dimPressure
void createIntegratedDataFiles()
Create the integrated-data files.
Definition: forces.C:406
volVectorField & moment()
Return access to the moment field.
Definition: forces.C:111
Basic thermodynamics type based on the use of fitting functions for cp, h, s obtained from the templa...
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO...
const dimensionSet dimForce
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
void reset()
Reset containers and fields.
Definition: forces.C:181
void initialise()
Initialise containers and fields.
Definition: forces.C:139
OBJstream os(runTime.globalPath()/outputName)
addToRunTimeSelectionTable(functionObject, ObukhovLength, dictionary)
virtual bool read(const dictionary &dict)
Read.
Definition: writeFile.C:241
labelList f(nPoints)
void setCoordinateSystem(const dictionary &dict, const word &e3Name=word::null, const word &e1Name=word::null)
Set the co-ordinate system from dictionary and axes names.
Definition: forces.C:45
const dimensionSet dimDensity
static const GeometricField< symmTensor, fvPatchField, volMesh > & null()
Return a null geometric field.
const dimensionedScalar mu
Atomic mass unit.
Field< tensor > tensorField
Specialisation of Field<T> for tensor.
autoPtr< coordinateSystem > coordSysPtr_
Coordinate system used when evaluating forces and moments.
Definition: forces.H:377
U
Definition: pEqn.H:72
#define WarningInFunction
Report a warning using Foam::Warning.
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:50
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
forces(const word &name, const Time &runTime, const dictionary &dict, const bool readFields=true)
Construct from Time and dictionary.
Definition: forces.C:523
const objectRegistry & obr_
Reference to the region objectRegistry.
Nothing to be read.
#define Log
Definition: PDRblock.C:28
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
messageStream Info
Information stream (stdout output on master, null elsewhere)
virtual bool read(const dictionary &dict)
Read optional controls.
Field< vector > vectorField
Specialisation of Field<T> for vector.
List< label > labelList
A List of labels.
Definition: List.H:62
volScalarField & p
A class for managing temporary objects.
Definition: HashPtrTable.H:50
void writeIntegratedDataFileHeader(const word &header, OFstream &os) const
Write header for an integrated-data file.
Definition: forces.C:423
Registry of regIOobjects.
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:172
void logIntegratedData(const string &descriptor, const vector &pres, const vector &vis, const vector &internal) const
Write integrated data to stream.
Definition: forces.C:496
Request registration (bool: true)
labelList cellIDs
volScalarField & nu
virtual bool write()
Write to data files/fields and to streams.
Definition: forces.C:839
Namespace for OpenFOAM.
SymmTensor< Cmpt > devTwoSymm(const SymmTensor< Cmpt > &st)
Return the deviatoric part of twice the symmetric part of a SymmTensor.
Definition: SymmTensorI.H:491
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127