phaseForces.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2018-2026 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "phaseForces.H"
28 #include "fvcGrad.H"
29 #include "dragModel.H"
30 #include "virtualMassModel.H"
31 #include "liftModel.H"
32 #include "wallLubricationModel.H"
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39 namespace functionObjects
40 {
43 }
44 }
45 
46 
47 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
48 
50 (
51  const word& name,
52  const Time& runTime,
53  const dictionary& dict
54 )
55 :
56  fvMeshFunctionObject(name, runTime, dict),
57  phaseName_(dict.lookup<word>("phase")),
58  forceFields_(nullptr)
59 {
60  read(dict);
61 }
62 
63 
64 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
65 
67 {}
68 
69 
70 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
71 
73 {
75 
76  return true;
77 }
78 
79 
81 {
82  const phaseSystem& fluid =
83  mesh_.lookupObject<phaseSystem>(phaseSystem::propertiesName);
84 
85  const phaseModel& phase = fluid.phases()[phaseName_];
86 
87  // Construct the force fields if needed
88  if (!forceFields_.valid())
89  {
90  forceFields_.set(new HashPtrTable<volVectorField>());
91 
92  forAll(fluid.phases(), phasei)
93  {
94  const phaseModel& otherPhase = fluid.phases()[phasei];
95 
96  if (&otherPhase == &phase) continue;
97 
98  const phaseInterface interface(phase, otherPhase);
99 
100  if (fluid.foundInterfacialModel<blendedDragModel>(interface))
101  {
102  forceFields_().insert
103  (
105  new volVectorField
106  (
107  IOobject
108  (
109  IOobject::groupName("dragForce", phase.name()),
110  mesh_.time().name(),
111  mesh_
112  ),
113  mesh_,
115  )
116  );
117  }
118 
119  if (fluid.foundInterfacialModel<blendedVirtualMassModel>(interface))
120  {
121  forceFields_().insert
122  (
124  new volVectorField
125  (
126  IOobject
127  (
129  (
130  "virtualMassForce",
131  phase.name()
132  ),
133  mesh_.time().name(),
134  mesh_
135  ),
136  mesh_,
138  )
139  );
140  }
141 
142  if (fluid.foundInterfacialModel<blendedLiftModel>(interface))
143  {
144  forceFields_().insert
145  (
147  new volVectorField
148  (
149  IOobject
150  (
151  IOobject::groupName("liftForce", phase.name()),
152  mesh_.time().name(),
153  mesh_
154  ),
155  mesh_,
157  )
158  );
159  }
160 
161  if
162  (
164  <
166  >(interface)
167  )
168  {
169  forceFields_().insert
170  (
172  new volVectorField
173  (
174  IOobject
175  (
177  (
178  "wallLubricationForce",
179  phase.name()
180  ),
181  mesh_.time().name(),
182  mesh_
183  ),
184  mesh_,
186  )
187  );
188  }
189 
190  if
191  (
193  <
195  >(interface)
196  )
197  {
198  forceFields_().insert
199  (
201  new volVectorField
202  (
203  IOobject
204  (
206  (
207  "turbulentDispersionForce",
208  phase.name()
209  ),
210  mesh_.time().name(),
211  mesh_
212  ),
213  mesh_,
215  )
216  );
217  }
218  }
219  }
220 
221  // Zero the force fields
223  (
225  forceFields_(),
226  forceFieldIter
227  )
228  {
229  *forceFieldIter() = Zero;
230  }
231 
232  // Add the forces from all the interfaces which contain this phase
233  forAll(fluid.phases(), phasei)
234  {
235  const phaseModel& otherPhase = fluid.phases()[phasei];
236 
237  if (&otherPhase == &phase) continue;
238 
239  const phaseInterface interface(phase, otherPhase);
240 
241  if (fluid.foundInterfacialModel<blendedDragModel>(interface))
242  {
243  forceFields_()[dragModel::typeName] +=
244  fluid.lookupInterfacialModel<blendedDragModel>(interface).K()
245  *interface.Ur(otherPhase);
246  }
247 
248  if (fluid.foundInterfacialModel<blendedVirtualMassModel>(interface))
249  {
250  forceFields_()[virtualMassModel::typeName] +=
252  <
254  >(interface).K()
255  *interface.DUDtr(otherPhase);
256  }
257 
258  if (fluid.foundInterfacialModel<blendedLiftModel>(interface))
259  {
260  forceFields_()[liftModel::typeName] +=
261  (&interface.phase1() == &phase ? -1 : +1)
262  *fluid.lookupInterfacialModel<blendedLiftModel>(interface).F();
263  }
264 
265  if
266  (
268  <
270  >(interface)
271  )
272  {
273  forceFields_()[wallLubricationModel::typeName] +=
274  (&interface.phase1() == &phase ? -1 : +1)
276  <
278  >(interface).F();
279  }
280 
281  if
282  (
284  <
286  >(interface)
287  )
288  {
289  forceFields_()[turbulentDispersionModel::typeName] +=
291  <
293  >(interface).D()
294  *fvc::grad
295  (
296  otherPhase
297  /max(phase + otherPhase, otherPhase.residualAlpha())
298  );
299  }
300  }
301 
302  return true;
303 }
304 
305 
307 {
309  (
311  forceFields_(),
312  forceFieldIter
313  )
314  {
315  writeObject(forceFieldIter()->name());
316  }
317 
318  return true;
319 }
320 
321 
322 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:492
Macros for easy insertion into run-time selection tables.
Generic GeometricField class.
A HashTable specialisation for hashing pointers.
Definition: HashPtrTable.H:68
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
static word groupName(Name name, const word &group)
autoPtr< T > set(const label, const word &key, T *)
Set element to pointer provided and return old element.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
tmp< volVectorField > F() const
Return lift force.
Definition: liftModel.C:59
tmp< volVectorField > F() const
Return wall lubrication force.
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
Abstract base-class for Time/database functionObjects.
Specialisation of Foam::functionObject for an Foam::fvMesh, providing a reference to the Foam::fvMesh...
virtual bool read(const dictionary &)
Read optional controls.
This functionObject calculates and outputs the blended interfacial forces acting on a given phase,...
Definition: phaseForces.H:102
virtual bool read(const dictionary &dict)
Read the input data.
Definition: phaseForces.C:72
phaseForces(const word &name, const Time &runTime, const dictionary &)
Construct from Time and dictionary.
Definition: phaseForces.C:50
virtual ~phaseForces()
Destructor.
Definition: phaseForces.C:66
virtual bool execute()
Calculate the force fields.
Definition: phaseForces.C:80
virtual bool write()
Write the force fields.
Definition: phaseForces.C:306
Class to represent an interface between phases. Derivations can further specify the configuration of ...
tmp< volVectorField > DUDtr(const phaseModel &phase) const
Convective acceleration of the phase relative to the other phase.
tmp< volVectorField > Ur(const phaseModel &phase) const
Velocity of the phase relative to the other phase.
const phaseModel & phase1() const
Return phase 1.
const dimensionedScalar & residualAlpha() const
Return the residual phase-fraction for given phase.
Definition: phaseModel.C:116
Class to represent a system of phases.
Definition: phaseSystem.H:74
bool foundInterfacialModel(const phaseInterface &interface) const
Check availability of a sub model for a given interface.
static const word propertiesName
Default name of the phase properties dictionary.
Definition: phaseSystem.H:252
const phaseModelList & phases() const
Return the phase models.
Definition: phaseSystemI.H:104
const ModelType & lookupInterfacialModel(const phaseInterface &interface) const
Return a sub model for an interface.
A class for handling words, derived from string.
Definition: word.H:63
Calculate the gradient of the given field.
K
Definition: pEqn.H:75
defineTypeNameAndDebug(fvMeshFunctionObject, 0)
addToRunTimeSelectionTable(functionObject, fvModel, dictionary)
tmp< VolField< typename outerProduct< vector, Type >::type > > grad(const SurfaceField< Type > &ssf)
Definition: fvcGrad.C:46
static const coefficient D("D", dimTemperature, 257.14)
const unitSet & lookup(const word &unitName)
Lookup and return the named unit from the table.
Definition: units.C:346
Namespace for OpenFOAM.
const dimensionSet & dimForce
Definition: dimensions.C:159
static const zero Zero
Definition: zero.H:97
String typeName(const std::type_info &info)
Return the un-mangled name given the standard type info.
const dimensionSet & dimVolume
Definition: dimensions.C:150
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
dictionary dict