sectionalForceProbes.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 
26 #include "sectionalForceProbes.H"
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 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
48 
50 {
51  return normal_;
52 }
53 
54 
56 {
57  return points_.first();
58 }
59 
60 
63 {
64  const scalar dot0 = points_.first() & normal_;
65  const scalar dot1 = points_.last() & normal_;
66 
67  tmp<scalarField> tdistances =
68  (pointField(points_, pointOrders_) & normal_) - dot0;
69  scalarField& distances = tdistances.ref();
70 
71  const scalar maxDistance = gMax(patchPointDistances());
72 
73  distances.append((1 + 2*small)*max(maxDistance, dot1 - dot0));
74 
75  return tdistances;
76 }
77 
78 
80 {
81  forAll(points_, i)
82  {
83  writeHeaderValue
84  (
85  file(),
86  "Point " + Foam::name(i),
87  points_[i]
88  );
89  }
90 
91  const Foam::Omanip<int> w = valueWidth(1);
92 
93  writeCommented(file(), "Point");
94 
95  forAll(points_, i)
96  {
97  file()
98  << w << i << w << ' ' << w << ' '
99  << w << ' ' << w << ' ' << w << ' ';
100  }
101  file().endl();
102 
103  writeCommented(file(), "Time");
104 
105  forAll(points_, i)
106  {
107  file()
108  << w << "Force" << w << ' ' << w << ' '
109  << w << "Moment" << w << ' ' << w << ' ';
110  }
111  file().endl();
112 
113  writeCommented(file(), "");
114 
115  forAll(points_, i)
116  {
117  file()
118  << w << 'x' << w << 'y' << w << 'z'
119  << w << 'x' << w << 'y' << w << 'z';
120  }
121  file().endl();
122 }
123 
124 
125 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
126 
128 (
129  const word& name,
130  const Time& runTime,
131  const dictionary& dict
132 )
133 :
134  sectionalForcesBase(name, runTime, dict),
135  logFiles(mesh(), name),
136  points_(),
137  pointOrders_()
138 {
139  read(dict);
140 }
141 
142 
143 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
144 
146 {}
147 
148 
149 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
150 
152 {
154 
155  normal_ = normalised(dict.lookup<vector>("normal"));
156  points_ = dict.lookup<List<point>>("points");
157 
158  if (points_.empty())
159  {
161  << "At least one point must be specified"
162  << exit(FatalIOError);
163  }
164 
165  // Check the points are in a line
166  SubField<vector> pointsNot0(points_, points_.size() - 1, 1);
167  const scalarField pointDeviation
168  (
169  mag((tensor::I - sqr(normal_)) & (pointsNot0 - points_.first()))
170  /mag(points_.last() - points_.first())
171  );
172  const scalar maxPointDeviation = max(pointDeviation);
173  if (maxPointDeviation > rootSmall)
174  {
176  << "Points of " << typeName << " function " << name()
177  << " are out of line in the direction " << normal_ << " by up to "
178  << maxPointDeviation*100 << "\% of the total span. This means"
179  << " that the moments computed at the points have different"
180  << " origins, and therefore may not be comparable." << endl;
181  }
182 
183  pointOrders_.setSize(points_.size());
184  sortedOrder((points_ & normal_)(), pointOrders_);
185 
186  resetName(typeName);
187 
188  return true;
189 }
190 
191 
193 {
194  logFiles::write();
195 
196  vectorField force(points_.size() + 1, Zero);
197  vectorField moment(points_.size() + 1, Zero);
198 
200 
201  force.map(force, pointOrders_);
202  moment.map(moment, pointOrders_);
203 
204  // Write out the graph
205  if (Pstream::master())
206  {
207  writeTime(file());
208 
209  const Foam::Omanip<int> w = valueWidth(1);
210 
211  forAll(points_, i)
212  {
213  file()
214  << w << force[i].x()
215  << w << force[i].y()
216  << w << force[i].z()
217  << w << moment[i].x()
218  << w << moment[i].y()
219  << w << moment[i].z();
220  }
221 
222  file().endl();
223  }
224 
225  return true;
226 }
227 
228 
229 // ************************************************************************* //
#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
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:91
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:178
Pre-declare related SubField type.
Definition: SubField.H:63
static const Tensor I
Definition: Tensor.H:83
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
T & first()
Return the first element of the list.
Definition: UListI.H:114
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
Calculates the magnitude of a field.
Definition: mag.H:59
This function calculates the fluid forces and moments at a number of section-planes through a given s...
sectionalForceProbes(const word &name, const Time &runTime, const dictionary &dict)
Construct from Time and dictionary.
virtual void writeFileHeader(const label i=0)
Output file header information.
virtual tmp< scalarField > distances() const
Return the distances from the origin to the section planes.
virtual point origin() const
Return the origin of the plot.
virtual vector normal() const
Return the normal to the section planes.
virtual bool write()
Write the sectionalForceProbes.
virtual bool read(const dictionary &)
Read the sectionalForceProbes 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.
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
#define WarningInFunction
Report a warning using Foam::Warning.
const dimensionSet force
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
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
tmp< DimensionedField< typename outerProduct< Type, Type >::type, GeoMesh, Field >> sqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
dimensionSet normalised(const dimensionSet &)
Definition: dimensionSet.C:509
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.
tmp< DimensionedField< scalar, GeoMesh, Field > > mag(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
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