rigidBodySectionalForcesBase.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) 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 
27 #include "rigidBodyMotion.H"
29 #include "pointMeshMover.H"
30 #include "transformField.H"
32 
33 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37 
38 vector AxCrossX(const tensor& A, const symmTensor& xSqr)
39 {
40  return
41  vector
42  (
43  A.yx()*xSqr.zx() + A.yy()*xSqr.zy() + A.yz()*xSqr.zz()
44  - A.zx()*xSqr.yx() - A.zy()*xSqr.yy() - A.zz()*xSqr.yz(),
45 
46  A.zx()*xSqr.xx() + A.zy()*xSqr.xy() + A.zz()*xSqr.xz()
47  - A.xx()*xSqr.zx() - A.xy()*xSqr.zy() - A.xz()*xSqr.zz(),
48 
49  A.xx()*xSqr.yx() + A.xy()*xSqr.yy() + A.xz()*xSqr.yz()
50  - A.yx()*xSqr.xx() - A.yy()*xSqr.xy() - A.yz()*xSqr.xz()
51  );
52 }
53 
55 {
56  tmp<vectorField> tresult(new vectorField(xSqr.size()));
57  vectorField& result = tresult.ref();
58  forAll(result, i)
59  {
60  result[i] = AxCrossX(A, xSqr[i]);
61  }
62  return tresult;
63 }
64 
65 }
66 
67 
68 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
69 
70 namespace Foam
71 {
72 namespace functionObjects
73 {
75 }
76 }
77 
78 
79 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
80 
83 {
84  const fvMeshMovers::pointMeshMover& mover =
85  refCast<const fvMeshMovers::pointMeshMover>(mesh_.mover());
86 
87  return refCast<const RBD::rigidBodyMotion>(mover.mover());
88 }
89 
90 
93 {
94  return motion().bodyIndex(body_);
95 }
96 
97 
100 {
101  return motion().bodies()[bodyIndex()];
102 }
103 
104 
106 {
107  return axisi_;
108 }
109 
110 
111 const Foam::word&
113 {
114  return coordSet::axisTypeNames_[axis_];
115 }
116 
117 
119 {
120  vector result = vector::zero;
121  result[axisi_] = 1;
122  return result;
123 }
124 
125 
126 const Foam::point&
128 {
129  return localOrigin_;
130 }
131 
132 
134 {
135  return motion().X0(bodyIndex()).E().vectorComponent(axisi_);
136 }
137 
138 
140 {
141  return motion().X0(bodyIndex()).inv().transformPoint(localOrigin_);
142 }
143 
144 
146 (
148  vectorField& moment
149 ) const
150 {
151  vectorField dForce(force.size(), vector::zero);
152  vectorField dMoment(moment.size(), vector::zero);
153 
154  // Calculate the fluid contribution
155  sectionalForcesBase::addFluid(dForce, dMoment);
156 
157  // Rotate into the body's coordinate frame
158  const tensor E = motion().X0(bodyIndex()).E();
159  transform(dForce, E, dForce);
160  transform(dMoment, E, dMoment);
161 
162  // Add to the total
163  force += dForce;
164  moment += dMoment;
165 }
166 
167 
169 (
171  vectorField& moment
172 ) const
173 {
174  tmp<scalarField> tdistances = this->distances();
175  const scalarField& distances = tdistances();
176 
177  // Get the velocity and acceleration in the frame of the body
178  const vector& v0 = motion().v(bodyIndex()).l();
179  const vector& w0 = motion().v(bodyIndex()).w();
180  const vector vDot0 = motion().a(bodyIndex()).l() - (v0 ^ w0);
181  const vector wDot0 = motion().a(bodyIndex()).w();
182  const tensor wDotXPlusWXWX(*wDot0 + (*w0 & *w0));
183 
184  // Get the moments of the body sections
185  const scalarField mu0s
186  (
187  body().sectionMu0s(axisi_, distances + localOrigin_[axisi_])
188  );
189  const vectorField mu1s
190  (
191  body().sectionMu1s(axisi_, distances + localOrigin_[axisi_])
192  );
193  const symmTensorField mu2s
194  (
195  body().sectionMu2s(axisi_, distances + localOrigin_[axisi_])
196  );
197 
198  // Calculate the body forces and moments on the intervals
199  const vectorField intervalForces
200  (
201  - (vDot0*mu0s)
202  - (wDotXPlusWXWX & mu1s)
203  );
204  const vectorField intervalMoments
205  (
206  (vDot0 ^ mu1s)
207  + AxCrossX(wDotXPlusWXWX, mu2s)
208  - (localOrigin_ ^ intervalForces)
209  );
210 
211  // Cumulatively sum the interval forces to obtain the sectional forces
213  forAllReverse(intervalForces, i)
214  {
215  f += intervalForces[i];
216  m += intervalMoments[i];
217  force[i] += f;
218  moment[i] += m - (distances[i]*axis() ^ f);
219  }
220 }
221 
222 
223 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
224 
227 (
228  const word& name,
229  const Time& runTime,
230  const dictionary& dict
231 )
232 :
233  sectionalForcesBase(name, runTime, dict),
234  body_()
235 {
236  read(dict);
237 }
238 
239 
240 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
241 
244 {}
245 
246 
247 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
248 
250 (
251  const dictionary& dict
252 )
253 {
255 
256  body_ = dict.lookup<word>("body");
257 
258  localOrigin_ = dict.lookupOrDefault<point>("origin", body().c());
259 
260  axis_ = coordSet::axisTypeNames_.read(dict.lookup("axis"));
261 
262  switch (coordSet::axisTypeNames_.read(dict.lookup("axis")))
263  {
267  break;
268  default:
270  << "Axis for " << typeName << " function '" << name()
271  << " must be "
275  << exit(FatalIOError);
276  }
277 
278  axisi_ =
279  static_cast<label>(axis_)
280  - static_cast<label>(coordSet::axisType::X);
281 
282  return true;
283 }
284 
285 
287 (
288  const polyMesh& mesh
289 )
290 {
291  if (&mesh == &mesh_)
292  {
293  // Don't clear the weights and directions. The patch transformation
294  // should be solid-body, so these don't change. The actual patch
295  // geometry does, though, so re-generate that.
296  clearPatchGeom();
297  }
298 }
299 
300 
301 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: UList.H:461
Macros for easy insertion into run-time selection tables.
#define w0
Definition: blockCreate.C:30
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
Enum read(Istream &) const
Read a word from Istream and return the corresponding.
Definition: NamedEnum.C:55
Six degree of freedom motion for a rigid body.
const Cmpt & xx() const
Definition: SymmTensorI.H:87
const Cmpt & yx() const
Definition: SymmTensorI.H:105
const Cmpt & yz() const
Definition: SymmTensorI.H:117
const Cmpt & xz() const
Definition: SymmTensorI.H:99
const Cmpt & zz() const
Definition: SymmTensorI.H:135
const Cmpt & xy() const
Definition: SymmTensorI.H:93
const Cmpt & zx() const
Definition: SymmTensorI.H:123
const Cmpt & zy() const
Definition: SymmTensorI.H:129
const Cmpt & yy() const
Definition: SymmTensorI.H:111
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
static const Form zero
Definition: VectorSpace.H:118
static const NamedEnum< axisType, 6 > axisTypeNames_
String representation of axis enums.
Definition: coordSet.H:69
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
const fvMesh & mesh_
Reference to the fvMesh.
Base class for rigid-body sectional forces function objects.
const RBD::rigidBodyMotion & motion() const
Return the motion system.
label axisi() const
Return the axis on which to plot the result.
label bodyIndex() const
Return the index of the body.
vector axis() const
Return the vector axis on which to plot the result. Note that this.
const point & localOrigin() const
Return the local origin of the plot.
rigidBodySectionalForcesBase(const word &name, const Time &runTime, const dictionary &dict)
Construct from Time and dictionary.
virtual void movePoints(const polyMesh &)
Update for mesh point-motion.
void addFluid(vectorField &force, vectorField &moment) const
Calculate the forces and moments at the cuts.
const word & axisName() const
Return the name of the axis on which to plot the result.
const RBD::rigidBody & body() const
Return the body.
virtual point origin() const
Return the origin of the plot.
virtual vector normal() const
Return the normal to the section planes.
void addBody(vectorField &force, vectorField &moment) const
Calculate the forces and moments at the cuts.
virtual bool read(const dictionary &)
Read the rigidBodySectionalForcesBase data.
Base class for sectional forces function objects.
void addFluid(vectorField &force, vectorField &moment) const
Calculate the forces and moments at the cuts.
virtual bool read(const dictionary &)
Read the sectionalForcesBase data.
Wrapper class so that a pointMeshMover can be instantiated to move an fvMesh.
const Foam::pointMeshMover & mover() const
Return the pointMeshMover.
const fvMeshMover & mover() const
Return the mover function class.
Definition: fvMesh.C:1125
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:78
A class for managing temporary objects.
Definition: tmp.H:55
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:197
Template function which returns the un-mangled name of a given type. Useful for types which do not ha...
A class for handling words, derived from string.
Definition: word.H:63
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
const dimensionSet force
defineTypeNameAndDebug(fvMeshFunctionObject, 0)
static const coefficient A("A", dimPressure, 611.21)
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
bool read(const char *, int32_t &)
Definition: int32IO.C:85
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
void transform(GeometricField< Type, GeoMesh > &rtf, const GeometricField< tensor, GeoMesh > &trf, const GeometricField< Type, GeoMesh > &tf)
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:49
Field< vector > vectorField
Specialisation of Field<T> for vector.
IOerror FatalIOError
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
vector AxCrossX(const tensor &A, const symmTensor &xSqr)
labelList f(nPoints)
dictionary dict
Spatial transformation functions for primitive fields.