immersedBoundaryForces.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | foam-extend: Open Source CFD
4  \\ / O peration | Version: 3.2
5  \\ / A nd | Web: http://www.foam-extend.org
6  \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
8 License
9  This file is part of foam-extend.
10 
11  foam-extend is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by the
13  Free Software Foundation, either version 3 of the License, or (at your
14  option) any later version.
15 
16  foam-extend is distributed in the hope that it will be useful, but
17  WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "immersedBoundaryForces.H"
30 #include "volFields.H"
31 #include "surfaceFields.H"
32 #include "dictionary.H"
33 #include "foamTime.H"
34 
35 using namespace Foam::incompressible::RASModels;
36 
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38 
39 namespace Foam
40 {
41  defineTypeNameAndDebug(immersedBoundaryForces, 0);
42 }
43 
44 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
45 
47 (
48  const word& name,
49  const objectRegistry& obr,
50  const dictionary& dict,
51  const bool loadFromFiles
52 )
53 :
54  forces
55  (
56  name,
57  obr,
58  dict,
59  loadFromFiles
60  )
61 {}
62 
63 
64 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
65 
67 {}
68 
69 
70 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
71 
72 Foam::immersedBoundaryForces::forcesMoments
74 {
75  forcesMoments fm
76  (
77  pressureViscous(vector::zero, vector::zero),
78  pressureViscous(vector::zero, vector::zero)
79  );
80 
81  if (directForceDensity_)
82  {
83  const volVectorField& fD = obr_.lookupObject<volVectorField>(fDName_);
84 
85  const fvMesh& mesh = fD.mesh();
86 
87  forAllConstIter(labelHashSet, patchSet_, iter)
88  {
89  label patchI = iter.key();
90 
91  // Check and cast into immersed boundary type
92  if
93  (
94  isA<immersedBoundaryFvPatchVectorField>
95  (
96  fD.boundaryField()[patchI]
97  )
98  )
99  {
100  // Found immersed boundary patch and field.
101  // Cast into immersed boundary type
102  const immersedBoundaryFvPatch& ibPatch =
103  refCast<const immersedBoundaryFvPatch>
104  (
105  mesh.boundary()[patchI]
106  );
107 
108  const immersedBoundaryFvPatchVectorField& fDpatch =
109  refCast<const immersedBoundaryFvPatchVectorField>
110  (
111  fD.boundaryField()[patchI]
112  );
113 
114  // Get ibPatch data on the whole surface mesh
115  const tmp<vectorField> fDTriF = fDpatch.triValue();
116  const vectorField& triCf = ibPatch.triCf();
117  const vectorField& Sfb = ibPatch.triSf();
118 
119  // Get triangular surface area vectors
120  const tmp<vectorField> tSfbTriFInM = ibPatch.renumberField(Sfb);
121  const vectorField& SfbTriFInM = tSfbTriFInM();
122  const scalarField sA = mag(SfbTriFInM);
123 
124  // Calculate distance for triangles
125  vectorField Md = ibPatch.renumberField(triCf) - CofR_;
126 
127  // Old treatment:
128  // Normal force =
129  // surfaceNormal*(surfaceUnitNormal & forceDensity)
130  // The first operation will be done on ibPoints, the data will
131  // then be distributed onto the ib surface
132  // for surface integration
133 // vectorField fN =
134 // Sfb*
135 // ibPatch.toTriFaces
136 // (
137 // ibPatch.ibNormals() & fDpatch.ibValue()
138 // );
139 
140  // New treatment: normal force calculated on triangles
141  // Damir Rigler, 30/Apr/2014
142  vectorField fN =
143  SfbTriFInM/sA*
144  (SfbTriFInM & ibPatch.renumberField(fDTriF()));
145 
146  fm.first().first() += sum(fN);
147  fm.second().first() += sum(Md ^ fN);
148 
149  // Tangential force (total force minus normal fN)
150  vectorField fT = sA*ibPatch.renumberField(fDTriF()) - fN;
151 
152  fm.first().second() += sum(fT);
153  fm.second().second() += sum(Md ^ fT);
154  }
155  }
156  }
157  else
158  {
159  const volVectorField& U = obr_.lookupObject<volVectorField>(UName_);
160  const volScalarField& p = obr_.lookupObject<volScalarField>(pName_);
161 
162  const fvMesh& mesh = U.mesh();
163 
164  // Scale pRef by density for incompressible simulations
165  scalar pRef = pRef_/rho(p);
166 
167  forAllConstIter(labelHashSet, patchSet_, iter)
168  {
169  label patchI = iter.key();
170 
171  // Check and cast into immersed boundary type
172  if
173  (
174  isA<immersedBoundaryFvPatch>
175  (
176  mesh.boundary()[patchI]
177  )
178  )
179  {
180  // Found immersed boundary patch and field.
181  // Cast into immersed boundary type
182  const immersedBoundaryFvPatchScalarField& pPatch =
183  refCast<const immersedBoundaryFvPatchScalarField>
184  (
185  p.boundaryField()[patchI]
186  );
187 
188  const immersedBoundaryFvPatch& ibPatch = pPatch.ibPatch();
189 
190  // Get ibPatch data on the whole surface mesh
191  const tmp<scalarField> pTriF = pPatch.triValue();
192  const vectorField& triCf = ibPatch.triCf();
193  const vectorField& Sfb = ibPatch.triSf();
194 
195  // Get triangular surface area vectors
196  const tmp<vectorField> tSfbTriFInM = ibPatch.renumberField(Sfb);
197  const vectorField& SfbTriFInM = tSfbTriFInM();
198  const scalarField sA = mag(SfbTriFInM);
199 
200  // Calculate distance for triangles
201  vectorField Md = ibPatch.renumberField(triCf) - CofR_;
202 
203  // Pressure force is an integral of interpolated pressure
204  // on triangular faces
205  vectorField pf =
206  SfbTriFInM*(ibPatch.renumberField(pTriF()) - pRef);
207 
208  fm.first().first() += rho(p)*sum(pf);
209  fm.second().first() += rho(p)*sum(Md ^ pf);
210 
211  if
212  (
213  isA<immersedBoundaryVelocityWallFunctionFvPatchVectorField>
214  (
215  U.boundaryField()[patchI]
216  )
217  )
218  {
219  // Turbulent wall functions
220 
221  // Get immersed boundary velocity. Used to access wall
222  // shear stress
223  const
225  UPatch = refCast
226  <
227  const
229  >
230  (
231  U.boundaryField()[patchI]
232  );
233 
234  // Integrate wall shear stress on triangular faces and get
235  // the part inside the mesh
237  ibPatch.toTriFaces(UPatch.wallShearStress());
238 
239  // Shear force is obtained from velocity wall functions
240  // and integrated on triangular faces
241  vectorField vf =
242  sA*ibPatch.renumberField(wallShearStress());
243 
244  fm.first().second() += sum(vf);
245  fm.second().second() += sum(Md ^ vf);
246  }
247  else if
248  (
249  isA<immersedBoundaryFvPatchVectorField>
250  (
251  U.boundaryField()[patchI]
252  )
253  )
254  {
255  // Laminar flow
256 
257  // Get immersed boundary velocity
258  const immersedBoundaryFvPatchVectorField& UPatch =
259  refCast<const immersedBoundaryFvPatchVectorField>
260  (
261  U.boundaryField()[patchI]
262  );
263 
264  // Look up the viscosity
265  if (mesh.foundObject<dictionary>("transportProperties"))
266  {
267  const dictionary& transportProperties =
268  mesh.lookupObject<dictionary>
269  (
270  "transportProperties"
271  );
272 
273  dimensionedScalar nu(transportProperties.lookup("nu"));
274 
275  // Integrate wall shear stress on triangular
276  // faces and get the part inside the mesh
277  const tmp<vectorField> grad = UPatch.triGrad();
278 
279  vectorField vf =
280  sA*rho(p)*nu.value()*ibPatch.renumberField(grad());
281 
282  fm.first().second() += sum(vf);
283  fm.second().second() += sum(Md ^ vf);
284  }
285  else
286  {
287  InfoIn
288  (
289  "immersedBoundaryForces::forcesMoments"
290  "immersedBoundaryForces::calcForcesMoment() const"
291  ) << "Laminar flow, but cannot find nu. Skipping"
292  << endl;
293  }
294  }
295  }
296  }
297  }
298 
299  reduce(fm, sumOp());
300 
301  return fm;
302 }
303 
304 
305 // ************************************************************************* //
volFields.H
InfoIn
#define InfoIn(functionName)
Report a information message using Foam::Info.
Definition: messageStream.H:276
Foam::fvc::grad
tmp< GeometricField< typename outerProduct< vector, Type >::type, fvPatchField, volMesh >> grad(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Definition: fvcGrad.C:52
Foam::Vector< scalar >::zero
static const Vector zero
Definition: Vector.H:80
p
p
Definition: pEqn.H:62
Foam::word
A class for handling words, derived from string.
Definition: word.H:59
Foam::immersedBoundaryForces::~immersedBoundaryForces
virtual ~immersedBoundaryForces()
Destructor.
Definition: immersedBoundaryForces.C:66
foamTime.H
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:118
Foam::immersedBoundaryForces::calcForcesMoment
virtual forcesMoments calcForcesMoment() const
Calculate and return forces and moment.
Definition: immersedBoundaryForces.C:73
Foam::immersedBoundaryFvPatch::triSf
const vectorField & triSf() const
Return triangular surface face area vectors.
Definition: immersedBoundaryFvPatch.C:2558
Foam::incompressible::RASModels::immersedBoundaryVelocityWallFunctionFvPatchVectorField
Boundary condition for velocity when using wall functions.
Definition: immersedBoundaryVelocityWallFunctionFvPatchVectorField.H:55
Foam::dictionary::lookup
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:449
Foam::GeometricField::boundaryField
GeometricBoundaryField & boundaryField()
Return reference to GeometricBoundaryField.
Definition: GeometricField.C:735
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
surfaceFields.H
Foam::surfaceFields.
Foam::mag
dimensioned< scalar > mag(const dimensioned< Type > &)
Foam::HashSet< label, Hash< label > >
Foam::incompressible::RASModels
Definition: immersedBoundaryEpsilonWallFunctionFvPatchScalarField.C:39
U
U
Definition: pEqn.H:46
forAllConstIter
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:39
Foam::objectRegistry
Registry of regIOobjects.
Definition: objectRegistry.H:50
nu
volScalarField & nu
Definition: readMechanicalProperties.H:179
immersedBoundaryVelocityWallFunctionFvPatchVectorField.H
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:43
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::immersedBoundaryFvPatch
Immersed boundary FV patch.
Definition: immersedBoundaryFvPatch.H:66
Foam::incompressible::RASModels::defineTypeNameAndDebug
defineTypeNameAndDebug(kkLOmega, 0)
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::dictionary
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:137
pRef
scalar pRef
Definition: createFields.H:19
Foam::immersedBoundaryFvPatch::triCf
const vectorField & triCf() const
Return triangular surface face centres.
Definition: immersedBoundaryFvPatch.C:2569
immersedBoundaryFvPatchFields.H
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
Foam::dimensioned
Generic dimensioned Type class.
Definition: dimensionedScalarFwd.H:41
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::refCast
To & refCast(From &r)
Reference type cast template function.
Definition: typeInfo.H:106
rho
rho
Definition: pEqn.H:3
Foam::immersedBoundaryForces::immersedBoundaryForces
immersedBoundaryForces(const word &name, const objectRegistry &, const dictionary &, const bool loadFromFiles=false)
Construct for given objectRegistry and dictionary.
Definition: immersedBoundaryForces.C:47
Foam::forces
This function object calculates the forces and moments by integrating the pressure and skin-friction ...
Definition: forces.H:234
Foam::incompressible::RASModels::immersedBoundaryVelocityWallFunctionFvPatchVectorField::wallShearStress
const vectorField & wallShearStress() const
Return wall shear stress.
Definition: immersedBoundaryVelocityWallFunctionFvPatchVectorField.C:191
Foam::sumOp
Definition: ops.H:162
dictionary.H
Foam::sum
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:333
immersedBoundaryFvPatch.H
immersedBoundaryForces.H
Foam::immersedBoundaryFvPatch::renumberField
const tmp< Field< Type > > renumberField(const Field< Type > &f) const
Renumber Field to corespond to triangular faces contained.
Foam::GeometricField
Generic GeometricField class.
Definition: surfaceFieldsFwd.H:52
Foam::name
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
Foam::immersedBoundaryFvPatch::toTriFaces
tmp< Field< Type > > toTriFaces(const Field< Type > &ibValues) const
triFace values: collect data from IB fields onto intersection
Foam::wallShearStress
This function object evaluates and outputs the shear stress at wall patches. The result is written as...
Definition: wallShearStress.H:131