58 { trackDirType::FORWARD,
"forward" },
59 { trackDirType::BACKWARD,
"backward" },
88 dict_.subDict(
"seedSampleSet")
91 sampledSetAxis_ = sampledSetPtr_->axis();
94 return *sampledSetPtr_;
125 addressing[nFaces++] =
pp.start()+i;
155 for (
const word& fieldName : fields_)
157 if (foundObject<volScalarField>(fieldName))
161 else if (foundObject<volVectorField>(fieldName))
168 <<
"Cannot find scalar/vector field " << fieldName <<
nl
169 <<
"Valid scalar fields: "
171 <<
"Valid vector fields: "
176 vsInterp.resize(nScalar);
177 vvInterp.resize(nVector);
181 for (
const word& fieldName : fields_)
183 if (foundObject<volScalarField>(fieldName))
193 else if (foundObject<volVectorField>(fieldName))
203 if (
f.name() == UName_)
206 UInterp.
cref(vvInterp[nVector]);
220 interpolationScheme_,
222 lookupObject<volVectorField>(UName_)
228 scalarNames_.resize(vsInterp.size());
231 scalarNames_[i] = vsInterp[i].psi().name();
233 vectorNames_.resize(vvInterp.size());
236 vectorNames_[i] = vvInterp[i].psi().name();
244 allTracks_.setCapacity(nSeeds);
245 allScalars_.resize(vsInterp.size());
248 allScalars_[i].clear();
249 allScalars_[i].setCapacity(nSeeds);
251 allVectors_.resize(vvInterp.size());
254 allVectors_[i].clear();
285 const scalarList& trackVals = allScalars_[i][tracki];
286 newVals[i] =
lerp(trackVals[lefti], trackVals[righti], w);
296 const vectorList& trackVals = allVectors_[i][tracki];
297 newVals[i] =
lerp(trackVals[lefti], trackVals[righti], w);
306 const treeBoundBox& bb,
308 PtrList<DynamicList<point>>& newTracks,
309 PtrList<DynamicList<scalarList>>& newScalars,
310 PtrList<DynamicList<vectorList>>& newVectors
313 const List<point>& track = allTracks_[tracki];
320 segmenti < track.size();
324 const point& startPt = track[segmenti-1];
325 const point& endPt = track[segmenti];
327 const vector d(endPt-startPt);
328 const scalar magD =
mag(d);
329 if (magD > ROOTVSMALL)
331 if (bb.contains(startPt))
347 if (!bb.contains(endPt))
350 if (bb.intersects(endPt, startPt, clipPt))
358 mag(clipPt-startPt)/magD,
367 newTracks.back().shrink();
368 newScalars.
back().shrink();
369 newVectors.
back().shrink();
378 if (bb.intersects(startPt, endPt, clipPt))
381 const label defltCapacity(track.size()/10);
388 mag(clipPt-startPt)/magD,
392 newTracks.emplace_back(defltCapacity),
397 if (!bb.contains(endPt))
411 mag(clipPt-startPt)/magD,
420 newTracks.back().shrink();
421 newScalars.
back().shrink();
422 newVectors.
back().shrink();
430 if (bb.contains(track.back()))
453 PtrList<DynamicList<point>> newTracks;
454 PtrList<DynamicList<scalarList>> newScalars;
455 PtrList<DynamicList<vectorList>> newVectors;
457 forAll(allTracks_, tracki)
459 const List<point>& track = allTracks_[tracki];
464 newTracks.emplace_back(track.size());
465 newScalars.emplace_back(track.size());
466 newVectors.emplace_back(track.size());
469 trimToBox(bb, tracki, newTracks, newScalars, newVectors);
474 allTracks_.
setSize(newTracks.size());
475 forAll(allTracks_, tracki)
477 allTracks_[tracki].transfer(newTracks[tracki]);
480 forAll(allScalars_, scalari)
482 DynamicList<scalarList>& fieldVals = allScalars_[scalari];
483 fieldVals.setSize(newTracks.size());
487 scalarList& trackVals = allScalars_[scalari][tracki];
488 trackVals.
setSize(newScalars[tracki].size());
489 forAll(trackVals, samplei)
491 trackVals[samplei] = newScalars[tracki][samplei][scalari];
496 forAll(allVectors_, vectori)
498 DynamicList<vectorList>& fieldVals = allVectors_[vectori];
499 fieldVals.setSize(newTracks.size());
502 vectorList& trackVals = allVectors_[vectori][tracki];
503 trackVals.
setSize(newVectors[tracki].size());
504 forAll(trackVals, samplei)
506 trackVals[samplei] = newVectors[tracki][samplei][vectori];
520 globalIndex globalTrackIDs(allTracks_.size());
535 fromProc.
setSize(globalTrackIDs.localSize(proci));
538 fromProc[i] = tracki++;
544 toMaster.
setSize(globalTrackIDs.localSize());
550 const mapDistribute distMap
552 globalTrackIDs.totalSize(),
565 distMap.constructSize(),
568 distMap.constructMap(),
573 allTracks_.setCapacity(allTracks_.size());
576 forAll(allScalars_, scalari)
578 allScalars_[scalari].shrink();
583 distMap.constructSize(),
586 distMap.constructMap(),
588 allScalars_[scalari],
591 allScalars_[scalari].setCapacity(allScalars_[scalari].size());
594 forAll(allVectors_, vectori)
596 allVectors_[vectori].shrink();
601 distMap.constructSize(),
604 distMap.constructMap(),
606 allVectors_[vectori],
609 allVectors_[vectori].setCapacity(allVectors_[vectori].size());
615 HashTable<fileName> outputFileNames;
619 if (!bounds_.empty())
622 trimToBox(treeBoundBox(bounds_));
628 forAll(allTracks_, tracki)
630 if (allTracks_[tracki].size())
633 n += allTracks_[tracki].size();
637 Log <<
" Tracks:" << nTracks <<
nl
638 <<
" Total samples:" <<
n
650 /
name()/mesh_.regionName()
651 / mesh_.time().timeName()
658 PtrList<coordSet> tracks(nTracks);
660 labelList oldToNewTrack(allTracks_.size(), -1);
662 forAll(allTracks_, tracki)
664 if (allTracks_[tracki].size())
666 List<point>&
points = allTracks_[tracki];
669 for (label pointi = 1; pointi <
points.size(); ++pointi)
682 std::move(allTracks_[tracki]),
686 oldToNewTrack[tracki] = nTracks;
692 const bool canWrite =
696 && trackWriterPtr_->enabled()
697 && (!allScalars_.empty() || !allVectors_.empty())
702 auto&
writer = trackWriterPtr_();
704 writer.nFields(allScalars_.size() + allVectors_.size());
709 (vtkPath / tracks[0].
name())
714 if (!allScalars_.empty())
716 List<List<scalarField>> scalarValues(allScalars_.size());
718 forAll(allScalars_, scalari)
720 auto& allTrackVals = allScalars_[scalari];
721 scalarValues[scalari].resize(nTracks);
723 forAll(allTrackVals, tracki)
728 const label newTracki = oldToNewTrack[tracki];
729 scalarValues[scalari][newTracki].transfer(vals);
737 writer.write(scalarNames_[i], scalarValues[i]);
739 outputFileNames.insert
742 time_.relativePath(outFile,
true)
747 if (!allVectors_.empty())
749 List<List<vectorField>> vectorValues(allVectors_.size());
751 forAll(allVectors_, vectori)
753 auto& allTrackVals = allVectors_[vectori];
754 vectorValues[vectori].setSize(nTracks);
756 forAll(allTrackVals, tracki)
761 const label newTracki = oldToNewTrack[tracki];
762 vectorValues[vectori][newTracki].transfer(vals);
770 writer.write(vectorNames_[i], vectorValues[i]);
772 outputFileNames.insert
775 time_.relativePath(outFile,
true)
792 const word& fieldName = iter.key();
806 const word& newUName,
864 UName_ =
dict.getOrDefault<
word>(
"U",
"U");
865 Info<<
" Employing velocity field " << UName_ <<
endl;
869 dict.readEntry(
"fields", fields_);
873 if (
dict.readIfPresent(
"trackForward", trackForward))
878 ? trackDirType::FORWARD
879 : trackDirType::BACKWARD
882 if (
dict.found(
"direction"))
885 <<
"Cannot specify both 'trackForward' and 'direction'" <<
nl
891 trackDir_ = trackDirTypeNames.getOrDefault
895 trackDirType::FORWARD
898 dict.readEntry(
"lifeTime", lifeTime_);
902 <<
"Illegal value " << lifeTime_ <<
" for lifeTime"
907 trackLength_ = VGREAT;
908 if (
dict.readIfPresent(
"trackLength", trackLength_))
910 Info<<
type() <<
" : fixed track length specified : "
911 << trackLength_ <<
nl <<
endl;
916 if (
dict.readIfPresent(
"bounds", bounds_) && !bounds_.empty())
918 Info<<
" clipping all segments to " << bounds_ <<
nl <<
endl;
922 interpolationScheme_ =
dict.getOrDefault
924 "interpolationScheme",
925 interpolationCellPoint<scalar>::typeName
930 cloudName_ =
dict.getOrDefault<word>(
"cloud",
type());
932 sampledSetPtr_.clear();
933 sampledSetAxis_.clear();
Field reading functions for post-processing utilities.
IOdictionary propsDict(dictIO)
word setFormat(propsDict.getOrDefault< word >("setFormat", "vtk"))
vtk::lineWriter writer(edgeCentres, edgeList::null(), fileName(aMesh.time().globalPath()/(vtkBaseFileName+"-edgesCentres")))
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
void setSize(const label n)
Alias for resize().
T & emplace_back(Args &&... args)
Construct an element at the end of the list, return reference to the new list element.
void push_back(const T &val)
Copy append an element to the end of this list.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
A HashTable similar to std::unordered_map.
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
A List with indirect addressing.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
void setSize(label n)
Alias for resize().
void resize(const label len)
Adjust allocated size of list.
static FOAM_NO_DANGLING_REFERENCE const meshSearchMeshObject & New(const polyMesh &mesh, Args &&... args)
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie,...
T & emplace_back(Args &&... args)
Construct and append an element to the end of the list, return reference to the new list element.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
T & back()
Access last element of the list, position [size()-1].
void size(const label n)
Older name for setAddressableSize.
@ scheduled
"scheduled" (MPI standard) : (MPI_Send, MPI_Recv)
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run.
@ broadcast
broadcast [MPI]
static bool & parRun() noexcept
Test if this a parallel run.
bool empty() const noexcept
True if the list is empty (ie, size() is zero).
label size() const noexcept
The number of entries in the list.
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
static autoPtr< coordSetWriter > New(const word &writeFormat)
Return a reference to the selected writer.
Holds list of sampling positions.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
A class for handling file names.
virtual bool read(const dictionary &dict)
Read and set the function object if its data have changed.
static word outputPrefix
Directory prefix.
Specialization of Foam::functionObject for an Foam::fvMesh, providing a reference to the Foam::fvMesh...
const fvMesh & mesh_
Reference to the fvMesh.
fvMeshFunctionObject(const fvMeshFunctionObject &)=delete
No copy construct.
const ObjectType & lookupObject(const word &fieldName) const
Lookup and return object (eg, a field) from the (sub) objectRegistry.
bool foundObject(const word &fieldName) const
Find object (eg, a field) in the (sub) objectRegistry.
void setProperty(const word &entryName, const Type &value)
Add generic property.
autoPtr< sampledSet > sampledSetPtr_
Seed set engine.
word cloudName_
Optional specified name of particles.
const sampledSet & sampledSetPoints() const
Demand driven construction of the sampledSet.
virtual ~streamLineBase()
Destructor.
word UName_
Field to transport particle with.
word sampledSetAxis_
Axis of the sampled points to output.
streamLineBase(const word &name, const Time &runTime, const dictionary &dict)
Construct for given objectRegistry and dictionary.
boundBox bounds_
Optional trimming of tracks.
label lifeTime_
Maximum lifetime (= number of cells) of particle.
autoPtr< indirectPrimitivePatch > wallPatch() const
Construct patch out of all wall patch faces.
List< DynamicList< scalarList > > allScalars_
Per scalarField, per track, the sampled values.
const word & sampledSetAxis() const
The axis of the sampledSet. Creates sampledSet if required.
trackDirType trackDir_
Whether to use +U, -U or both.
dictionary dict_
Input dictionary.
scalar trackLength_
Track length.
virtual bool read(const dictionary &dict)
Read the field average data.
void storePoint(const label tracki, const scalar w, const label lefti, const label righti, DynamicList< point > &newTrack, DynamicList< List< scalar > > &newScalars, DynamicList< List< vector > > &newVectors) const
Generate point and values by interpolating from existing values.
virtual void resetFieldNames(const word &newUName, const wordList &newFieldNames)
Reset the field names.
refPtr< interpolation< vector > > initInterpolations(const label nSeeds, PtrList< interpolation< scalar > > &vsInterp, PtrList< interpolation< vector > > &vvInterp)
Initialise interpolators and track storage.
wordList fields_
List of fields to sample.
autoPtr< coordSetWriter > trackWriterPtr_
File writer for tracks data.
trackDirType
Enumeration defining the track direction.
@ FORWARD
Use "forward" tracking.
@ BIDIRECTIONAL
Use "bidirectional" tracking.
@ BACKWARD
Use "backward" tracking.
List< DynamicList< vectorList > > allVectors_
Per vectorField, per track, the sampled values.
static const Enum< trackDirType > trackDirTypeNames
Names for the trackDir.
virtual bool writeToFile()
Write tracks to file.
virtual void movePoints(const polyMesh &)
Update for mesh point-motion.
wordList scalarNames_
Names of scalar fields.
word interpolationScheme_
Interpolation scheme to use.
wordList vectorNames_
Names of vector fields.
virtual void updateMesh(const mapPolyMesh &)
Update for changes of mesh.
void trimToBox(const treeBoundBox &bb, const label tracki, PtrList< DynamicList< point > > &newTracks, PtrList< DynamicList< scalarList > > &newScalars, PtrList< DynamicList< vectorList > > &newVectors) const
Trim and possibly split a track.
virtual void track()=0
Do the actual tracking to fill the track data.
virtual bool execute()
Execute the averaging.
virtual bool write()
Track and write.
DynamicList< List< point > > allTracks_
All tracks. Per track the points it passed through.
const Time & time_
Reference to the time database.
Calculates a non-overlapping list of offsets based on an input size (eg, number of cells) from differ...
label totalSize() const noexcept
The total addressed size, which corresponds to the end offset and also the sum of all localSizes.
label localSize(const label proci) const
Size of proci data.
Given cell centre values and point (vertex) values decompose into tetrahedra and linear interpolate w...
Abstract base class for volume field interpolation.
static autoPtr< interpolation< Type > > New(const word &interpolationType, const GeometricField< Type, fvPatchField, volMesh > &psi)
Return a reference to the specified interpolation scheme.
const labelListList & constructMap() const noexcept
From subsetted data to new reconstructed data.
static List< labelPair > schedule(const labelListList &subMap, const labelListList &constructMap, const int tag, const label comm=UPstream::worldComm)
Calculate a communication schedule. See above.
const labelListList & subMap() const noexcept
From subsetted data back to original data.
static void distribute(const UPstream::commsTypes commsType, const UList< labelPair > &schedule, const label constructSize, const labelListList &subMap, const bool subHasFlip, const labelListList &constructMap, const bool constructHasFlip, List< T > &field, const T &nullValue, const CombineOp &cop, const NegateOp &negOp, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Distribute combine data with specified combine operation and negate operator (for flips).
label constructSize() const noexcept
Constructed data size.
Class containing processor-to-processor mapping information.
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
const polyMesh & mesh() const noexcept
Return polyMesh.
A polyBoundaryMesh is a polyPatch list with registered IO, a reference to the associated polyMesh,...
Mesh consisting of general polyhedral cells.
A patch is a list of labels that address the faces in the global face list.
A class for managing references or pointers (no reference counting).
const T & cref() const
Return const reference to the object or to the contents of a (non-null) managed pointer.
void clear() const noexcept
If object pointer points to valid object: delete object and set pointer to nullptr.
void reset(T *p=nullptr) noexcept
Delete managed pointer and set to new given pointer.
Holds list of sampling points which is filled at construction time. Various implementations of this b...
static autoPtr< sampledSet > New(const word &name, const polyMesh &mesh, const meshSearch &searchEngine, const dictionary &dict)
Return a reference to the selected sampledSet.
Standard boundBox with extra functionality for use in octree.
bool intersects(const point &overallStart, const vector &overallVec, const point &start, const point &end, point &pt, direction &ptBits) const
Intersects segment; set point to intersection position and face,.
bool contains(const vector &dir, const point &) const
Contains point (inside or on edge) and moving in direction.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
A class for handling words, derived from Foam::string.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
const polyBoundaryMesh & patches
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
word outputName("finiteArea-edges.obj")
Function objects are OpenFOAM utilities to ease workflow configurations and enhance workflows.
List< word > wordList
List of word.
GeometricField< vector, fvPatchField, volMesh > volVectorField
List< labelList > labelListList
List of labelList.
bool read(const char *buf, int32_t &val)
Same as readInt32.
List< label > labelList
A List of labels.
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
messageStream Info
Information stream (stdout output on master, null elsewhere).
List< vector > vectorList
List of vector.
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Ostream & endl(Ostream &os)
Add newline and flush stream.
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
vector point
Point is a vector.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
errorManipArg< error, int > exit(error &err, const int errNo=1)
List< scalar > scalarList
List of scalar.
dimensioned< Type > lerp(const dimensioned< Type > &a, const dimensioned< Type > &b, const scalar t)
constexpr char nl
The newline '\n' character (0x0a).
#define forAll(list, i)
Loop across all elements in list.
#define forAllConstIters(container, iter)
Iterate across all elements of the container object with const access.
Functor to negate primitives. Dummy for most other types.