streamlines.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) 2011-2025 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 "streamlines.H"
27 #include "streamlinesCloud.H"
28 #include "sampledSet.H"
29 #include "globalIndex.H"
30 #include "interpolationCellPoint.H"
31 #include "PatchTools.H"
32 #include "writeFile.H"
33 #include "polyTopoChangeMap.H"
34 #include "polyMeshMap.H"
35 #include "polyDistributionMap.H"
36 #include "OSspecific.H"
38 
39 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 
41 namespace Foam
42 {
43 
44 template<class Type>
46 {
47  List<List<Type>> gatheredField(Pstream::nProcs());
48  gatheredField[Pstream::myProcNo()] = field;
49  Pstream::gatherList(gatheredField);
50 
51  field =
52  ListListOps::combine<List<Type>>
53  (
54  gatheredField,
56  );
57 }
58 
59 }
60 
61 
62 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
63 
64 namespace Foam
65 {
66  namespace functionObjects
67  {
70  }
71 }
72 
75 {
76  "forward",
77  "backward",
78  "both"
79 };
80 
81 
82 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
83 
85 (
86  const word& name,
87  const Time& runTime,
88  const dictionary& dict
89 )
90 :
91  fvMeshFunctionObject(name, runTime, dict),
92  nSubCycle_(0)
93 {
94  read(dict);
95 }
96 
97 
98 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
99 
101 {}
102 
103 
104 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
105 
107 {
108  Info<< type() << " " << name() << ":" << nl;
109 
110  dict.lookup("fields") >> fields_;
111 
112  UName_ = dict.lookupOrDefault("U", word("U"));
113 
114  writeAge_ = dict.lookupOrDefault<Switch>("writeAge", true);
115 
116  trackDirection_ = trackDirectionNames_[word(dict.lookup("direction"))];
117 
118  trackOutside_ = dict.lookupOrDefault<Switch>("outside", false);
119 
120  dict.lookup("lifeTime") >> lifeTime_;
121 
122  if (lifeTime_ < 1)
123  {
125  << "Illegal value " << lifeTime_ << " for lifeTime"
126  << exit(FatalError);
127  }
128 
129  bool subCycling = dict.found("nSubCycle");
130  bool fixedLength = dict.found("trackLength");
131  if (subCycling && fixedLength)
132  {
134  << "Cannot both specify automatic time stepping (through '"
135  << "nSubCycle' specification) and fixed track length (through '"
136  << "trackLength')"
137  << exit(FatalIOError);
138  }
139  if (subCycling)
140  {
141  nSubCycle_ = max(dict.lookup<scalar>("nSubCycle"), 1);
142  trackLength_ = vGreat;
143  Info<< " automatic track length specified through"
144  << " number of sub cycles : " << nSubCycle_ << nl << endl;
145  }
146  else
147  {
148  nSubCycle_ = 1;
149  dict.lookup("trackLength") >> trackLength_;
150  Info<< " fixed track length specified : "
151  << trackLength_ << nl << endl;
152  }
153 
154  interpolationScheme_ =
155  dict.lookupOrDefault
156  (
157  "interpolationScheme",
159  );
160 
161  cloudName_ = dict.lookupOrDefault<word>("cloudName", "streamlines");
162 
163  sampledSetPtr_ = sampledSet::New
164  (
165  "seedSampleSet",
166  mesh_,
167  dict.subDict("seedSampleSet")
168  );
169 
170  formatterPtr_ = setWriter::New(dict.lookup("setFormat"), dict);
171 
172  return true;
173 }
174 
175 
177 {
178  wordList allFields(fields_);
179  allFields.append(UName_);
180 
181  return allFields;
182 }
183 
184 
186 {
187  return true;
188 }
189 
190 
192 {
193  Info<< type() << " " << name() << " write:" << nl;
194 
195  // Create list of available fields
197  forAll(fields_, fieldi)
198  {
199  if
200  (
201  false
202  #define FoundTypeField(Type, nullArg) \
203  || foundObject<VolField<Type>>(fields_[fieldi])
205  #undef FoundTypeField
206  )
207  {
208  fieldNames.append(fields_[fieldi]);
209  }
210  else
211  {
212  cannotFindObject(fields_[fieldi]);
213  }
214  }
215 
216  // Lookup fields and construct interpolators
217  #define DeclareTypeInterpolator(Type, nullArg) \
218  PtrList<interpolation<Type>> Type##Interp(fieldNames.size());
220  #undef DeclareTypeInterpolator
221  forAll(fieldNames, fieldi)
222  {
223  #define ConstructTypeInterpolator(Type, nullArg) \
224  if (mesh_.foundObject<VolField<Type>>(fieldNames[fieldi])) \
225  { \
226  Type##Interp.set \
227  ( \
228  fieldi, \
229  interpolation<Type>::New \
230  ( \
231  interpolationScheme_, \
232  mesh_.lookupObject<VolField<Type>>(fieldNames[fieldi]) \
233  ) \
234  ); \
235  }
237  #undef ConstructTypeInterpolator
238  }
239 
240  // Create a velocity interpolator if it is not already available
241  const label UIndex = findIndex(fieldNames, UName_);
242  tmpNrc<interpolation<vector>> UInterp(nullptr);
243  if (UIndex == -1)
244  {
245  UInterp =
247  (
249  (
250  interpolationScheme_,
251  mesh_.lookupObject<volVectorField>(UName_)
252  ).ptr()
253  );
254  }
255 
256  // Get the mesh searching engine
257  const meshSearch& searchEngine = meshSearch::New(mesh_);
258 
259  // Do tracking to create sampled data
260  DynamicField<point> allPositions;
261  DynamicField<label> allTracks;
262  DynamicField<label> allTrackParts;
263  DynamicField<scalar> allAges;
264  #define DeclareAllTypes(Type, nullArg) \
265  List<DynamicField<Type>> all##Type##s(fieldNames.size());
267  #undef DeclareAllTypes
268  {
269  // Create a cloud and initialise with points from the sampled set
270  globalIndex gi(sampledSetPtr_().size());
272  (
273  mesh_,
274  cloudName_,
276  );
277  label nLocateBoundaryHits;
278  forAll(sampledSetPtr_(), i)
279  {
280  particles.addParticle
281  (
283  (
284  searchEngine,
285  sampledSetPtr_().positions()[i],
286  sampledSetPtr_().cells()[i],
287  nLocateBoundaryHits,
288  lifeTime_,
289  gi.toGlobal(i)
290  )
291  );
292  }
293 
294  // Report the number of successful seeds
295  const label nSeeds = returnReduce(particles.size(), sumOp<label>());
296  Info << " Seeded " << nSeeds << " particles" << endl;
297 
298  // Create tracking data
300  (
301  particles,
302  #define TypeInterpolatorParameter(Type, nullArg) \
303  Type##Interp,
306  UIndex != -1 ? vectorInterp[UIndex] : UInterp(),
307  trackDirection_ == trackDirection::forward,
308  trackOutside_,
309  nSubCycle_,
310  trackLength_,
311  allPositions,
312  allTracks,
313  allTrackParts,
314  allAges
315  #define AllTypesParameter(Type, nullArg) \
316  , all##Type##s
318  #undef AllTypesParameter
319  );
320 
321  // Track
322  IDLList<streamlinesParticle> initialParticles;
323  if (trackDirection_ == trackDirection::both)
324  {
325  initialParticles = particles;
326  }
327 
328  particles.move(particles, td);
329 
330  if (trackDirection_ == trackDirection::both)
331  {
332  particles.IDLList<streamlinesParticle>::operator=(initialParticles);
333  td.trackForward_ = !td.trackForward_;
334  particles.move(particles, td);
335  }
336  }
337 
338  // Gather data on the master
339  if (Pstream::parRun())
340  {
341  gatherAndFlatten(allPositions);
342  gatherAndFlatten(allTracks);
343  gatherAndFlatten(allTrackParts);
344  gatherAndFlatten(allAges);
345  forAll(fieldNames, fieldi)
346  {
347  #define GatherAndFlattenAllTypes(Type, nullArg) \
348  if (Type##Interp.set(fieldi)) \
349  { \
350  gatherAndFlatten(all##Type##s[fieldi]); \
351  }
353  #undef GatherAndFlattenAllTypes
354  }
355  }
356 
357  // Report the total number of samples
358  Info<< " Sampled " << allPositions.size() << " locations" << endl;
359 
360  // Bin-sort by track and trackPart to build an ordering
361  labelList order(allPositions.size());
362  if (Pstream::master() && allPositions.size())
363  {
364  const label nTracks = max(allTracks) + 1;
365  const label trackParti0 = min(allTrackParts);
366  const label trackParti1 = max(allTrackParts) + 1;
367 
368  labelListList trackPartCounts
369  (
370  nTracks,
371  labelList(trackParti1 - trackParti0, 0)
372  );
373  forAll(allPositions, samplei)
374  {
375  const label tracki = allTracks[samplei];
376  const label trackParti = -trackParti0 + allTrackParts[samplei];
377  trackPartCounts[tracki][trackParti] ++;
378  }
379 
380  label offset = 0;
381  labelListList trackPartOffsets
382  (
383  nTracks,
384  labelList(trackParti1 - trackParti0, 0)
385  );
386  forAll(trackPartOffsets, tracki)
387  {
388  forAll(trackPartOffsets[tracki], trackParti)
389  {
390  trackPartOffsets[tracki][trackParti] += offset;
391  offset += trackPartCounts[tracki][trackParti];
392  }
393  }
394 
395  forAll(trackPartCounts, tracki)
396  {
397  trackPartCounts[tracki] = 0;
398  }
399 
400  forAll(allPositions, samplei)
401  {
402  const label tracki = allTracks[samplei];
403  const label trackParti = -trackParti0 + allTrackParts[samplei];
404 
405  order[samplei] =
406  trackPartOffsets[tracki][trackParti]
407  + trackPartCounts[tracki][trackParti];
408 
409  trackPartCounts[tracki][trackParti] ++;
410  }
411  }
412 
413  //auto reportTrackParts = [&]()
414  //{
415  // Info<< nl;
416  // forAll(allPositions, samplei)
417  // {
418  // if
419  // (
420  // samplei == 0
421  // || allTracks[samplei] != allTracks[samplei - 1]
422  // || allTrackParts[samplei] != allTrackParts[samplei - 1]
423  // )
424  // {
425  // Info<< "track #" << allTracks[samplei]
426  // << " part #" << allTrackParts[samplei]
427  // << " from i=" << samplei << " to ";
428  // }
429  // if
430  // (
431  // samplei == allPositions.size() - 1
432  // || allTracks[samplei + 1] != allTracks[samplei]
433  // || allTrackParts[samplei + 1] != allTrackParts[samplei]
434  // )
435  // {
436  // Info<< "i=" << samplei << nl;
437  // }
438  // }
439  //};
440 
441  //reportTrackParts();
442 
443  // Reorder
444  if (Pstream::master())
445  {
446  allPositions.rmap(allPositions, order);
447  allTracks.rmap(allTracks, order);
448  allTrackParts.rmap(allTrackParts, order);
449  allAges.rmap(allAges, order);
450  forAll(fieldNames, fieldi)
451  {
452  #define RMapAllTypes(Type, nullArg) \
453  if (Type##Interp.set(fieldi)) \
454  { \
455  all##Type##s[fieldi].rmap(all##Type##s[fieldi], order); \
456  }
458  #undef RMapAllTypes
459  }
460  }
461 
462  //reportTrackParts();
463 
464  // Relabel tracks and track parts into track labels only, and join the
465  // forward and backward track parts that are connected to the seed
466  if (Pstream::master())
467  {
468  label samplei = 0, tracki = 0;
469  forAll(allPositions, samplej)
470  {
471  const label trackj = allTracks[samplej];
472  const label trackPartj = allTrackParts[samplej];
473 
474  allPositions[samplei] = allPositions[samplej];
475  allTracks[samplei] = tracki;
476  allTrackParts[samplei] = 0;
477  allAges[samplei] = allAges[samplej];
478  forAll(fieldNames, fieldi)
479  {
480  #define ShuffleUpAllTypes(Type, nullArg) \
481  if (Type##Interp.set(fieldi)) \
482  { \
483  all##Type##s[fieldi][samplei] = \
484  all##Type##s[fieldi][samplej]; \
485  }
487  #undef ShuffleUpAllTypes
488  }
489 
490  const bool joinNewParts =
491  samplej != allPositions.size() - 1
492  && trackPartj == -1
493  && allTrackParts[samplej + 1] == 0;
494 
495  if (!joinNewParts) samplei ++;
496 
497  const bool newPart =
498  samplej == allPositions.size() - 1
499  || trackj != allTracks[samplej + 1]
500  || trackPartj != allTrackParts[samplej + 1];
501 
502  if (!joinNewParts && newPart) tracki ++;
503  }
504 
505  allPositions.resize(samplei);
506  allTracks.resize(samplei);
507  allTrackParts.resize(samplei);
508  allAges.resize(samplei);
509  forAll(fieldNames, fieldi)
510  {
511  #define ResizeAllTypes(Type, nullArg) \
512  if (Type##Interp.set(fieldi)) \
513  { \
514  all##Type##s[fieldi].resize(samplei); \
515  }
517  #undef ResizeAllTypes
518  }
519  }
520 
521  //reportTrackParts();
522 
523  // Write
524  if (Pstream::master() && allPositions.size())
525  {
526  // Make output directory
527  const fileName outputPath =
528  time_.globalPath()
530  /(mesh_.name() != polyMesh::defaultRegion ? mesh_.name() : word())
531  /name()
532  /time_.name();
533  mkDir(outputPath);
534 
535  // Pass data to the formatter to write
536  const label nValueSets = fieldNames.size() + writeAge_;
537  wordList valueSetNames(nValueSets);
538  #define DeclareTypeValueSets(Type, nullArg) \
539  UPtrList<const Field<Type>> Type##ValueSets(nValueSets);
541  #undef DeclareTypeValueSets
542  if (writeAge_)
543  {
544  valueSetNames[0] = "age";
545  scalarValueSets.set(0, &allAges);
546  }
547  forAll(fieldNames, fieldi)
548  {
549  valueSetNames[fieldi + writeAge_] = fieldNames[fieldi];
550 
551  #define SetTypeValueSetPtr(Type, nullArg) \
552  if (Type##Interp.set(fieldi)) \
553  { \
554  Type##ValueSets.set \
555  ( \
556  fieldi + writeAge_, \
557  &all##Type##s[fieldi] \
558  ); \
559  }
561  #undef SetTypeValueSetPtr
562  }
563  formatterPtr_->write
564  (
565  outputPath,
566  "tracks",
567  coordSet(allTracks, word::null, allPositions),
568  valueSetNames
569  #define TypeValueSetsParameter(Type, nullArg) , Type##ValueSets
572  );
573  }
574 
575  Info<< endl;
576 
577  return true;
578 }
579 
580 
582 {
583  if (&mesh == &mesh_)
584  {
585  sampledSetPtr_->movePoints();
586  }
587 }
588 
589 
591 (
592  const polyTopoChangeMap& map
593 )
594 {
595  if (&map.mesh() == &mesh_)
596  {
597  sampledSetPtr_->topoChange(map);
598  }
599 }
600 
601 
603 (
604  const polyMeshMap& map
605 )
606 {
607  if (&map.mesh() == &mesh_)
608  {
609  sampledSetPtr_->mapMesh(map);
610  }
611 }
612 
613 
615 (
616  const polyDistributionMap& map
617 )
618 {
619  if (&map.mesh() == &mesh_)
620  {
621  sampledSetPtr_->distribute(map);
622  }
623 }
624 
625 
626 // ************************************************************************* //
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
Macros for easy insertion into run-time selection tables.
Dynamically sized Field.
Definition: DynamicField.H:72
void resize(const label)
Alter the addressed list size.
void rmap(const UList< Type > &mapF, const labelUList &mapAddressing)
1 to 1 reverse-map from the given field
Definition: Field.C:386
Generic GeometricField class.
Template class for intrusive linked lists.
Definition: ILList.H:67
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
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
Initialise the NamedEnum HashTable from the static list of names.
Definition: NamedEnum.H:55
static void gatherList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Gather data but keep individual values separate.
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:61
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
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:411
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:399
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:429
Holds list of sampling positions.
Definition: coordSet.H:51
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
A class for handling file names.
Definition: fileName.H:82
Abstract base-class for Time/database functionObjects.
Specialisation of Foam::functionObject for an Foam::fvMesh, providing a reference to the Foam::fvMesh...
This functionObject tracks a particle cloud in the specified velocity field of an incompressible flow...
Definition: particles.H:111
Generates streamline data by sampling a set of user-specified fields along a particle track,...
Definition: streamlines.H:208
streamlines(const word &name, const Time &runTime, const dictionary &dict)
Construct from Time and dictionary.
Definition: streamlines.C:85
virtual wordList fields() const
Return the list of fields required.
Definition: streamlines.C:176
virtual void topoChange(const polyTopoChangeMap &)
Update topology using the given map.
Definition: streamlines.C:591
virtual void distribute(const polyDistributionMap &)
Redistribute or update using the given distribution map.
Definition: streamlines.C:615
virtual ~streamlines()
Destructor.
Definition: streamlines.C:100
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
Definition: streamlines.C:603
virtual void movePoints(const polyMesh &)
Update for mesh point-motion.
Definition: streamlines.C:581
virtual bool execute()
Do nothing.
Definition: streamlines.C:185
virtual bool write()
Calculate and write the streamlines.
Definition: streamlines.C:191
virtual bool read(const dictionary &)
Read the field average data.
Definition: streamlines.C:106
static const NamedEnum< trackDirection, 3 > trackDirectionNames_
Track direction enumeration names.
Definition: streamlines.H:222
static const word outputPrefix
Directory prefix.
Definition: writeFile.H:72
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:64
label toGlobal(const label i) const
From local to global.
Definition: globalIndexI.H:82
Given cell centre values and point (vertex) values decompose into tetrahedra and linear interpolate w...
static autoPtr< interpolation< Type > > New(const word &interpolationType, const VolField< Type > &psi)
Return a reference to the specified interpolation scheme.
Definition: interpolation.C:56
Mesh object that implements searches within the local cells and faces.
Definition: meshSearch.H:59
static const meshSearch & New(const polyMesh &mesh, const pointInCellShapes=pointInCellShapes::tets)
Lookup or construct from mesh and cell decomposition option.
Definition: meshSearch.C:61
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
const polyMesh & mesh() const
Return polyMesh.
Class containing mesh-to-mesh mapping information.
Definition: polyMeshMap.H:51
const polyMesh & mesh() const
Return polyMesh.
Definition: polyMeshMap.H:75
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:78
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:251
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
const polyMesh & mesh() const
Return polyMesh.
static autoPtr< sampledSet > New(const word &name, const polyMesh &mesh, const dictionary &dict)
Return a reference to the selected sampledSet.
Definition: sampledSet.C:162
static autoPtr< setWriter > New(const word &writeType, const IOstream::streamFormat writeFormat=IOstream::ASCII, const IOstream::compressionType writeCompression=IOstream::UNCOMPRESSED)
Select given write options.
Definition: setWriter.C:286
A Cloud of streamlines particles.
Particle class that samples fields as it passes through. Used in streamlines calculation.
A class for managing temporary objects without reference counting.
Definition: tmpNrc.H:53
A class for handling words, derived from string.
Definition: word.H:62
static const word null
An empty word.
Definition: word.H:77
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 FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
static List< word > fieldNames
Definition: globalFoam.H:46
const cellShapeList & cells
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.name(), lagrangian::cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
defineTypeNameAndDebug(adjustTimeStepToCombustion, 0)
addToRunTimeSelectionTable(functionObject, adjustTimeStepToCombustion, dictionary)
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
List< label > labelList
A List of labels.
Definition: labelList.H:56
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
bool mkDir(const fileName &, mode_t=0777)
Make a directory and return an error if it could not be created.
Definition: POSIX.C:290
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:258
int order(const scalar s)
messageStream Info
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
IOerror FatalIOError
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
error FatalError
FOR_ALL_FIELD_TYPES(makeFieldSourceTypedef)
void offset(label &lst, const label o)
void gatherAndFlatten(DynamicField< Type > &field)
Definition: streamlines.C:45
static const char nl
Definition: Ostream.H:267
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
dictionary dict
#define FoundTypeField(Type, nullArg)
#define DeclareTypeValueSets(Type, nullArg)
#define SetTypeValueSetPtr(Type, nullArg)
#define DeclareAllTypes(Type, nullArg)
#define AllTypesParameter(Type, nullArg)
#define ResizeAllTypes(Type, nullArg)
#define TypeValueSetsParameter(Type, nullArg)
#define DeclareTypeInterpolator(Type, nullArg)
#define GatherAndFlattenAllTypes(Type, nullArg)
#define ConstructTypeInterpolator(Type, nullArg)
#define RMapAllTypes(Type, nullArg)
#define TypeInterpolatorParameter(Type, nullArg)
#define ShuffleUpAllTypes(Type, nullArg)