lumpedPointState.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2016-2020 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "lumpedPointState.H"
29 #include "unitConversion.H"
31 #include "IFstream.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 const Foam::Enum
36 <
38 >
40 ({
41  { inputFormatType::PLAIN, "plain" },
42  { inputFormatType::DICTIONARY, "dictionary" },
43 });
44 
45 
46 Foam::scalar Foam::lumpedPointState::visLength = 0.1;
47 
49 
50 
51 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
52 
54 static Foam::string getLineNoComment
55 (
56  Foam::ISstream& is,
57  const char comment = '#'
58 )
59 {
60  Foam::string line;
61  do
62  {
63  is.getLine(line);
64  }
65  while ((line.empty() || line[0] == comment) && is.good());
66 
67  return line;
68 }
70 
71 
72 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
73 
74 void Foam::lumpedPointState::calcRotations() const
75 {
76  rotationPtr_.reset(new tensorField(angles_.size()));
77 
78  auto rotIter = rotationPtr_->begin();
79 
80  for (const vector& angles : angles_)
81  {
82  *rotIter =
84 
85  ++rotIter;
86  }
87 }
88 
89 
90 void Foam::lumpedPointState::readDict
91 (
92  const dictionary& dict,
93  const quaternion::eulerOrder rotOrder,
94  const bool degrees
95 )
96 {
97  dict.readEntry("points", points_);
98  dict.readEntry("angles", angles_);
99  order_ =
101  (
102  "rotationOrder",
103  dict,
104  rotOrder
105  );
106 
107  degrees_ = dict.getOrDefault("degrees", degrees);
108 
109  rotationPtr_.reset(nullptr);
110 }
111 
112 
113 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
114 
116 :
117  points_(),
118  angles_(),
119  order_(quaternion::eulerOrder::ZXZ),
120  degrees_(false),
121  rotationPtr_(nullptr)
122 {}
123 
124 
126 :
127  points_(rhs.points_),
128  angles_(rhs.angles_),
129  order_(rhs.order_),
130  degrees_(rhs.degrees_),
131  rotationPtr_(nullptr)
132 {}
133 
134 
136 (
137  const pointField& pts,
138  const vectorField& ang,
139  const quaternion::eulerOrder rotOrder,
140  const bool degrees
141 )
142 :
143  points_(pts),
144  angles_(ang),
145  order_(rotOrder),
146  degrees_(degrees),
147  rotationPtr_(nullptr)
148 {
149  if (points_.size() != angles_.size())
150  {
151  #ifdef FULLDEBUG
153  << "Have " << points_.size() << " points but "
154  << angles_.size() << " angles" << nl
155  << exit(FatalError);
156  #else
158  << "Have " << points_.size() << " points but "
159  << angles_.size() << " angles, resizing angles to match" << nl;
160  #endif
161 
162  angles_.resize(points_.size(), Zero);
163  }
164 }
165 
166 
168 (
169  const pointField& pts,
170  const quaternion::eulerOrder rotOrder,
171  const bool degrees
172 )
173 :
174  points_(pts),
175  angles_(points_.size(), Zero),
176  order_(rotOrder),
177  degrees_(degrees),
178  rotationPtr_(nullptr)
179 {}
180 
181 
183 (
184  tmp<pointField>& pts,
185  const quaternion::eulerOrder rotOrder,
186  const bool degrees
187 )
188 :
189  points_(pts),
190  angles_(points_.size(), Zero),
191  order_(rotOrder),
192  degrees_(false),
193  rotationPtr_(nullptr)
194 {}
195 
196 
198 (
199  const dictionary& dict,
200  const quaternion::eulerOrder rotOrder,
201  const bool degrees
202 )
203 :
204  points_(),
205  angles_(),
206  order_(rotOrder),
207  degrees_(degrees),
208  rotationPtr_(nullptr)
209 {
210  readDict(dict, rotOrder, degrees);
211 }
212 
213 
214 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
215 
217 {
218  points_ = rhs.points_;
219  angles_ = rhs.angles_;
220  order_ = rhs.order_;
221  degrees_ = rhs.degrees_;
222 
223  rotationPtr_.reset(nullptr);
224 }
225 
226 
228 {
229  for (point& p : points_)
230  {
231  p += origin;
232  }
233 }
234 
235 
236 void Foam::lumpedPointState::scalePoints(const scalar scaleFactor)
237 {
238  if (scaleFactor > 0)
239  {
240  points_ *= scaleFactor;
241  }
242 }
243 
244 
246 (
247  const scalar alpha,
248  const lumpedPointState& prev
249 )
250 {
251  points_ = prev.points_ + alpha*(points_ - prev.points_);
252 
253  scalar convert = 1.0;
254  if (degrees_ != prev.degrees_)
255  {
256  if (prev.degrees_)
257  {
258  // Was degrees, now radians
259  convert = degToRad();
260  }
261  else
262  {
263  // Was radians, now degrees
264  convert = radToDeg();
265  }
266  }
267 
268  angles_ = convert*prev.angles_ + alpha*(angles_ - convert*prev.angles_);
269 
270  rotationPtr_.reset(nullptr);
271 }
272 
273 
275 (
276  Istream& is,
277  const quaternion::eulerOrder rotOrder,
278  const bool degrees
279 )
280 {
281  // Assume generic input stream so we can do line-based input
282  ISstream& iss = dynamic_cast<ISstream&>(is);
283 
284  string line = getLineNoComment(iss);
285 
286  label count;
287  {
288  IStringStream isstr(line);
289  isstr >> count;
290  }
291 
292  points_.resize(count);
293  angles_.resize(count);
294 
295  count = 0;
296  forAll(points_, i)
297  {
298  iss.getLine(line);
299  IStringStream isstr(line);
300 
301  isstr
302  >> points_[count].x() >> points_[count].y() >> points_[count].z()
303  >> angles_[count].x() >> angles_[count].y() >> angles_[count].z();
304 
305  ++count;
306  }
307 
308  points_.resize(count);
309  angles_.resize(count);
310  order_ = quaternion::eulerOrder::ZXZ;
311  degrees_ = false;
312 
313  rotationPtr_.reset(nullptr);
314 
315  return count;
316 }
317 
318 
320 (
321  Istream& is,
322  const quaternion::eulerOrder rotOrder,
323  const bool degrees
324 )
325 {
326  dictionary dict(is);
327  readDict(dict, rotOrder, degrees);
328 
329  return points_.size();
330 }
331 
332 
334 {
335  writeDict(os);
336  return true;
337 }
338 
339 
341 {
342  os.writeEntry("points", points_);
343  os.writeEntry("angles", angles_);
344  if (order_ != quaternion::eulerOrder::ZXZ)
345  {
346  os.writeEntry("order", quaternion::eulerOrderNames[order_]);
347  }
348  if (degrees_)
349  {
350  os.writeEntry("degrees", "true");
351  }
352 }
353 
354 
356 {
357  os <<"# input for OpenFOAM\n"
358  <<"# N, points, angles\n"
359  << points_.size() << "\n";
360 
361  forAll(points_, i)
362  {
363  const vector& p = points_[i];
364 
365  os << p.x() << ' ' << p.y() << ' ' << p.z();
366 
367  if (i < angles_.size())
368  {
369  os << ' ' << angles_[i].x()
370  << ' ' << angles_[i].y()
371  << ' ' << angles_[i].z() << '\n';
372  }
373  else
374  {
375  os << " 0 0 0\n";
376  }
377  }
378 }
379 
380 
382 (
383  const inputFormatType fmt,
384  const fileName& file,
385  const quaternion::eulerOrder rotOrder,
386  const bool degrees
387 )
388 {
389  bool ok = false;
390  if (Pstream::master())
391  {
392  IFstream is(file);
393 
394  if (fmt == inputFormatType::PLAIN)
395  {
396  ok = this->readPlain(is, rotOrder, degrees);
397  }
398  else
399  {
400  ok = this->readData(is, rotOrder, degrees);
401  }
402  }
403 
404  if (Pstream::parRun())
405  {
406  // Scatter master data using communication scheme
407 
408  const List<Pstream::commsStruct>& comms =
409  (
413  );
414 
415  // Get my communication order
416  const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
417 
418  // Receive from up
419  if (myComm.above() != -1)
420  {
421  IPstream fromAbove
422  (
424  myComm.above(),
425  0,
428  );
429 
430  fromAbove >> points_ >> angles_ >> degrees_;
431  }
432 
433  // Send to downstairs neighbours
434  forAllReverse(myComm.below(), belowI)
435  {
436  OPstream toBelow
437  (
439  myComm.below()[belowI],
440  0,
443  );
444 
445  toBelow << points_ << angles_ << degrees_;
446  }
447 
448  rotationPtr_.reset(nullptr);
449 
450  // MPI barrier
451  Pstream::scatter(ok);
452  }
453 
454  return ok;
455 }
456 
457 
458 // ************************************************************************* //
Foam::UPstream::linearCommunication
static const List< commsStruct > & linearCommunication(const label communicator=worldComm)
Communication schedule for linear all-to-master (proc 0)
Definition: UPstream.H:523
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::Enum
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: IOstreamOption.H:57
EulerCoordinateRotation.H
Foam::lumpedPointState::operator+=
void operator+=(const point &origin)
Shift points by specified origin.
Definition: lumpedPointState.C:227
Foam::lumpedPointState::writeDict
void writeDict(Ostream &os) const
Output as dictionary content.
Definition: lumpedPointState.C:340
Foam::ISstream::getLine
ISstream & getLine(std::string &str, char delim='\n')
Raw, low-level getline (until delimiter) into a string.
Definition: ISstreamI.H:76
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::IFstream
Input from file stream, using an ISstream.
Definition: IFstream.H:53
Foam::lumpedPointState::inputFormatType
inputFormatType
Input format types.
Definition: lumpedPointState.H:119
Foam::OPstream
Output inter-processor communications stream.
Definition: OPstream.H:53
Foam::lumpedPointState::operator=
void operator=(const lumpedPointState &rhs)
Assignment operator.
Definition: lumpedPointState.C:216
Foam::constant::atomic::alpha
const dimensionedScalar alpha
Fine-structure constant: default SI units: [].
Definition: readThermalProperties.H:212
Foam::lumpedPointState::relax
void relax(const scalar alpha, const lumpedPointState &prev)
Relax the state.
Definition: lumpedPointState.C:246
Foam::tensorField
Field< tensor > tensorField
Specialisation of Field<T> for tensor.
Definition: primitiveFieldsFwd.H:57
Foam::lumpedPointState::visUnused
static bool visUnused
Enable/disable visualization of unused points.
Definition: lumpedPointState.H:168
Foam::ISstream
Generic input stream using a standard (STL) stream.
Definition: ISstream.H:55
unitConversion.H
Unit conversion functions.
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:457
Foam::Pstream::scatter
static void scatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Scatter data. Distribute without modification. Reverse of gather.
Definition: gatherScatter.C:150
Foam::lumpedPointState::readPlain
bool readPlain(Istream &is, const quaternion::eulerOrder rotOrder=quaternion::eulerOrder::ZXZ, const bool degrees=false)
Read input as plain content.
Definition: lumpedPointState.C:275
Foam::string
A class for handling character strings derived from std::string.
Definition: string.H:76
Foam::UPstream::commsStruct::below
const labelList & below() const noexcept
Definition: UPstream.H:135
lumpedPointState.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::IOstream::good
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:233
Foam::quaternion
Quaternion class used to perform rotations in 3D space.
Definition: quaternion.H:56
Foam::lumpedPointState::readData
bool readData(Istream &is, const quaternion::eulerOrder rotOrder=quaternion::eulerOrder::ZXZ, const bool degrees=false)
Read input as dictionary content.
Definition: lumpedPointState.C:320
Foam::lumpedPointState
The state of lumped points corresponds to positions and rotations.
Definition: lumpedPointState.H:112
Foam::lumpedPointState::scalePoints
void scalePoints(const scalar scaleFactor)
Scale points by given factor.
Definition: lumpedPointState.C:236
Foam::Field< vector >
Foam::lumpedPointState::formatNames
static const Enum< inputFormatType > formatNames
Names for the input format types.
Definition: lumpedPointState.H:129
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::lumpedPointState::angles
const vectorField & angles() const
The orientation of the points (mass centres)
Definition: lumpedPointStateI.H:52
Foam::Enum::getOrDefault
EnumType getOrDefault(const word &key, const dictionary &dict, const EnumType deflt, const bool failsafe=false) const
Definition: Enum.C:179
Foam::lumpedPointState::writePlain
void writePlain(Ostream &os) const
Output as plain content.
Definition: lumpedPointState.C:355
Foam::dictionary::readEntry
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, bool mandatory=true) const
Definition: dictionaryTemplates.C:302
Foam::radToDeg
constexpr scalar radToDeg(const scalar rad) noexcept
Conversion from radians to degrees.
Definition: unitConversion.H:54
Foam::quaternion::eulerOrder
eulerOrder
Euler-angle rotation order.
Definition: quaternion.H:102
IFstream.H
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
os
OBJstream os(runTime.globalPath()/outputName)
Foam::lumpedPointState::writeData
bool writeData(Ostream &os) const
Output as dictionary content.
Definition: lumpedPointState.C:333
Foam::IStringStream
Input from string buffer, using a ISstream. Always UNCOMPRESSED.
Definition: StringStream.H:108
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
Foam::degToRad
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
Definition: unitConversion.H:48
Foam::UPstream::commsStruct
Structure for communicating between processors.
Definition: UPstream.H:83
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::UPstream::nProcsSimpleSum
static int nProcsSimpleSum
Definition: UPstream.H:278
Foam::quaternion::eulerOrderNames
static const Enum< eulerOrder > eulerOrderNames
The names for Euler-angle rotation order.
Definition: quaternion.H:112
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::UPstream::msgType
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:540
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=worldComm)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:463
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::UPstream::commsTypes::scheduled
Foam::BitOps::count
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition: BitOps.H:77
Foam::Vector< scalar >
Foam::UPstream::worldComm
static label worldComm
Default communicator (all processors)
Definition: UPstream.H:293
Foam::UPstream::parRun
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:433
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
Foam::line
A line primitive.
Definition: line.H:53
Foam::Ostream::writeEntry
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:236
Foam::UPstream::commsStruct::above
label above() const noexcept
Definition: UPstream.H:130
forAllReverse
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: stdFoam.H:309
Foam::IPstream
Input inter-processor communications stream.
Definition: IPstream.H:53
Foam::coordinateRotations::euler::rotation
static tensor rotation(const vector &angles, bool degrees=false)
Definition: EulerCoordinateRotation.C:239
Foam::UPstream::treeCommunication
static const List< commsStruct > & treeCommunication(const label communicator=worldComm)
Communication schedule for tree all-to-master (proc 0)
Definition: UPstream.H:532
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::lumpedPointState::lumpedPointState
lumpedPointState()
Default construct.
Definition: lumpedPointState.C:115
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:148
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328
Foam::lumpedPointState::visLength
static scalar visLength
The length for visualization triangles.
Definition: lumpedPointState.H:171
Foam::UPstream::nProcs
static label nProcs(const label communicator=worldComm)
Number of processes in parallel run, and 1 for serial run.
Definition: UPstream.H:445