rigidBodySectionalForceProbes.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 "fvMesh.H"
29 
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
31 
32 namespace Foam
33 {
34 namespace functionObjects
35 {
38  (
42  );
43 }
44 }
45 
46 
47 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
48 
50 Foam::functionObjects::rigidBodySectionalForceProbes::distances() const
51 {
52  tmp<scalarField> tdistances =
53  scalarField(coordinates_, coordinateOrders_)
54  - localOrigin()[axisi()];
55  scalarField& distances = tdistances.ref();
56 
57  const scalar maxDistance = gMax(patchPointDistances());
58 
59  distances.append((1 + 2*small)*max(maxDistance, distances.last()));
60 
61  return tdistances;
62 }
63 
64 
65 void Foam::functionObjects::rigidBodySectionalForceProbes::writeFileHeader
66 (
67  const label
68 )
69 {
70  forAll(coordinates_, i)
71  {
72  writeHeaderValue
73  (
74  file(),
75  "Coordinate " + Foam::name(i),
76  coordinates_[i]
77  );
78  }
79 
80  const Foam::Omanip<int> w = valueWidth(1);
81 
82  writeCommented(file(), "Coordinate");
83 
84  forAll(coordinates_, i)
85  {
86  file()
87  << w << i << w << ' ' << w << ' '
88  << w << ' ' << w << ' ' << w << ' '
89  << w << ' ' << w << ' ' << w << ' '
90  << w << ' ' << w << ' ' << w << ' '
91  << w << ' ' << w << ' ' << w << ' '
92  << w << ' ' << w << ' ' << w << ' ';
93  }
94  file().endl();
95 
96  writeCommented(file(), "Time");
97 
98  forAll(coordinates_, i)
99  {
100  file()
101  << w << "Fluid Force" << w << ' ' << w << ' '
102  << w << "Body Force" << w << ' ' << w << ' '
103  << w << "Total Force" << w << ' ' << w << ' '
104  << w << "Fluid Moment" << w << ' ' << w << ' '
105  << w << "Body Moment" << w << ' ' << w << ' '
106  << w << "Total Moment" << w << ' ' << w << ' ';
107  }
108  file().endl();
109 
110  writeCommented(file(), "");
111 
112  forAll(coordinates_, i)
113  {
114  file()
115  << w << 'x' << w << 'y' << w << 'z'
116  << w << 'x' << w << 'y' << w << 'z'
117  << w << 'x' << w << 'y' << w << 'z'
118  << w << 'x' << w << 'y' << w << 'z'
119  << w << 'x' << w << 'y' << w << 'z'
120  << w << 'x' << w << 'y' << w << 'z';
121  }
122  file().endl();
123 }
124 
125 
126 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
127 
130 (
131  const word& name,
132  const Time& runTime,
133  const dictionary& dict
134 )
135 :
137  logFiles(mesh(), name),
138  coordinates_(),
139  coordinateOrders_()
140 {
141  read(dict);
142 }
143 
144 
145 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
146 
149 {}
150 
151 
152 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
153 
155 (
156  const dictionary& dict
157 )
158 {
160 
161  coordinates_ = dict.lookup<List<scalar>>("coordinates");
162 
163  if (coordinates_.empty())
164  {
166  << "At least one coordinate must be specified"
167  << exit(FatalIOError);
168  }
169 
170  coordinateOrders_.setSize(coordinates_.size());
171  sortedOrder(coordinates_, coordinateOrders_);
172 
173  resetName(typeName);
174 
175  return true;
176 }
177 
178 
180 {
181  logFiles::write();
182 
183  vectorField fluidForce(coordinates_.size() + 1, Zero);
184  vectorField bodyForce(coordinates_.size() + 1, Zero);
185  vectorField totalForce(coordinates_.size() + 1, Zero);
186  vectorField fluidMoment(coordinates_.size() + 1, Zero);
187  vectorField bodyMoment(coordinates_.size() + 1, Zero);
188  vectorField totalMoment(coordinates_.size() + 1, Zero);
189 
190  // Calculate the fluid contribution
191  rigidBodySectionalForcesBase::addFluid(fluidForce, fluidMoment);
192 
193  // Calculate the body contribution
194  rigidBodySectionalForcesBase::addBody(bodyForce, bodyMoment);
195 
196  // Sum to create total sectional forces and moments
197  totalForce = fluidForce + bodyForce;
198  totalMoment = fluidMoment + bodyMoment;
199 
200  // Reorder to match that of the input coordinates
201  fluidForce.map(fluidForce, coordinateOrders_);
202  bodyForce.map(bodyForce, coordinateOrders_);
203  totalForce.map(totalForce, coordinateOrders_);
204  fluidMoment.map(fluidMoment, coordinateOrders_);
205  bodyMoment.map(bodyMoment, coordinateOrders_);
206  totalMoment.map(totalMoment, coordinateOrders_);
207 
208  // Write out the graph
209  if (Pstream::master())
210  {
211  writeTime(file());
212 
213  const Foam::Omanip<int> w = valueWidth(1);
214 
215  forAll(coordinates_, i)
216  {
217  file()
218  << w << fluidForce[i].x()
219  << w << fluidForce[i].y()
220  << w << fluidForce[i].z()
221  << w << bodyForce[i].x()
222  << w << bodyForce[i].y()
223  << w << bodyForce[i].z()
224  << w << totalForce[i].x()
225  << w << totalForce[i].y()
226  << w << totalForce[i].z()
227  << w << fluidMoment[i].x()
228  << w << fluidMoment[i].y()
229  << w << fluidMoment[i].z()
230  << w << bodyMoment[i].x()
231  << w << bodyMoment[i].y()
232  << w << bodyMoment[i].z()
233  << w << totalMoment[i].x()
234  << w << totalMoment[i].y()
235  << w << totalMoment[i].z();
236  }
237 
238  file().endl();
239  }
240 
241  return true;
242 }
243 
244 
245 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
Macros for easy insertion into run-time selection tables.
void map(const UList< Type > &mapF, const labelUList &mapAddressing)
1 to 1 map from the given field
Definition: Field.C:289
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:423
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.
functionObject base class for creating, maintaining and writing log files e.g. integrated of averaged...
Definition: logFiles.H:60
virtual bool write()
Write function.
Definition: logFiles.C:173
This function calculates the fluid and acceleration forces and moments at a number of section-planes ...
rigidBodySectionalForceProbes(const word &name, const Time &runTime, const dictionary &dict)
Construct from Time and dictionary.
virtual bool write()
Write the rigidBodySectionalForceProbes.
virtual bool read(const dictionary &)
Read the rigidBodySectionalForceProbes data.
Base class for rigid-body sectional forces function objects.
label axisi() const
Return the axis on which to plot the result.
const point & localOrigin() const
Return the local origin of the plot.
void addFluid(vectorField &force, vectorField &moment) const
Calculate the forces and moments at the cuts.
void addBody(vectorField &force, vectorField &moment) const
Calculate the forces and moments at the cuts.
virtual bool read(const dictionary &)
Read the rigidBodySectionalForcesBase data.
tmp< scalarField > patchPointDistances() const
Return the distance from the origin to the patch points.
A class for managing temporary objects.
Definition: tmp.H:55
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
defineTypeNameAndDebug(fvMeshFunctionObject, 0)
addToRunTimeSelectionTable(functionObject, fvModel, dictionary)
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
static const zero Zero
Definition: zero.H:97
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
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
IOerror FatalIOError
Type gMax(const UList< Type > &f, const label comm)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
void sortedOrder(const UList< T > &, labelList &order)
Generate the (stable) sort order for the list.
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
dictionary dict