43 namespace functionObjects
85 dict.lookup(
"fields") >> fields_;
87 UName_ =
dict.lookupOrDefault(
"U",
word(
"U"));
89 writeAge_ =
dict.lookupOrDefault<
Switch>(
"writeAge",
true);
91 trackDirection_ = trackDirectionNames_[
word(
dict.lookup(
"direction"))];
93 trackOutside_ =
dict.lookupOrDefault<
Switch>(
"outside",
false);
95 dict.lookup(
"lifeTime") >> lifeTime_;
100 <<
"Illegal value " << lifeTime_ <<
" for lifeTime"
104 bool subCycling =
dict.found(
"nSubCycle");
105 bool fixedLength =
dict.found(
"trackLength");
106 if (subCycling && fixedLength)
109 <<
"Cannot both specify automatic time stepping (through '"
110 <<
"nSubCycle' specification) and fixed track length (through '"
116 nSubCycle_ =
max(
dict.lookup<scalar>(
"nSubCycle"), 1);
117 trackLength_ = vGreat;
118 Info<<
indent <<
"automatic track length specified through"
119 <<
" number of sub cycles : " << nSubCycle_ <<
endl;
124 dict.lookup(
"trackLength") >> trackLength_;
125 Info<<
indent <<
" fixed track length specified : "
126 << trackLength_ <<
endl;
129 interpolationScheme_ =
132 "interpolationScheme",
136 cloudName_ =
dict.lookupOrDefault<
word>(
"cloudName",
"streamlines");
142 dict.subDict(
"seedSampleSet")
187 cannotFindObject(fields_[fieldi]);
192 #define DeclareTypeInterpolator(Type, nullArg) \
193 PtrList<interpolation<Type>> Type##Interp(fieldNames.size());
195 #undef DeclareTypeInterpolator
198 #define ConstructTypeInterpolator(Type, nullArg) \
199 if (mesh_.foundObject<VolField<Type>>(fieldNames[fieldi])) \
204 interpolation<Type>::New \
206 interpolationScheme_, \
207 mesh_.lookupObject<VolField<Type>>(fieldNames[fieldi]) \
212 #undef ConstructTypeInterpolator
225 interpolationScheme_,
239 #define DeclareAllTypes(Type, nullArg) \
240 List<DynamicField<Type>> all##Type##s(fieldNames.size());
242 #undef DeclareAllTypes
252 label nLocateBoundaryHits;
253 forAll(sampledSetPtr_(), i)
260 sampledSetPtr_().positions()[i],
261 sampledSetPtr_().
cells()[i],
281 UIndex != -1 ? vectorInterp[UIndex] : UInterp(),
282 trackDirection_ == trackDirection::forward,
298 if (trackDirection_ == trackDirection::both)
305 if (trackDirection_ == trackDirection::both)
322 #define ConcatenateListAllTypes(Type, nullArg) \
323 if (Type##Interp.set(fieldi)) \
325 Pstream::concatenateList(all##Type##s[fieldi]); \
328 #undef ConcatenateListAllTypes
339 const label nTracks =
max(allTracks) + 1;
340 const label trackParti0 =
min(allTrackParts);
341 const label trackParti1 =
max(allTrackParts) + 1;
348 forAll(allPositions, samplei)
350 const label tracki = allTracks[samplei];
351 const label trackParti = -trackParti0 + allTrackParts[samplei];
352 trackPartCounts[tracki][trackParti] ++;
361 forAll(trackPartOffsets, tracki)
363 forAll(trackPartOffsets[tracki], trackParti)
365 trackPartOffsets[tracki][trackParti] +=
offset;
366 offset += trackPartCounts[tracki][trackParti];
370 forAll(trackPartCounts, tracki)
372 trackPartCounts[tracki] = 0;
375 forAll(allPositions, samplei)
377 const label tracki = allTracks[samplei];
378 const label trackParti = -trackParti0 + allTrackParts[samplei];
381 trackPartOffsets[tracki][trackParti]
382 + trackPartCounts[tracki][trackParti];
384 trackPartCounts[tracki][trackParti] ++;
423 allTrackParts.
rmap(allTrackParts,
order);
427 #define RMapAllTypes(Type, nullArg) \
428 if (Type##Interp.set(fieldi)) \
430 all##Type##s[fieldi].rmap(all##Type##s[fieldi], order); \
443 label samplei = 0, tracki = 0;
444 forAll(allPositions, samplej)
446 const label trackj = allTracks[samplej];
447 const label trackPartj = allTrackParts[samplej];
449 allPositions[samplei] = allPositions[samplej];
450 allTracks[samplei] = tracki;
451 allTrackParts[samplei] = 0;
452 allAges[samplei] = allAges[samplej];
455 #define ShuffleUpAllTypes(Type, nullArg) \
456 if (Type##Interp.set(fieldi)) \
458 all##Type##s[fieldi][samplei] = \
459 all##Type##s[fieldi][samplej]; \
462 #undef ShuffleUpAllTypes
465 const bool joinNewParts =
466 samplej != allPositions.
size() - 1
468 && allTrackParts[samplej + 1] == 0;
470 if (!joinNewParts) samplei ++;
473 samplej == allPositions.
size() - 1
474 || trackj != allTracks[samplej + 1]
475 || trackPartj != allTrackParts[samplej + 1];
477 if (!joinNewParts && newPart) tracki ++;
480 allPositions.
resize(samplei);
481 allTracks.
resize(samplei);
482 allTrackParts.
resize(samplei);
486 #define ResizeAllTypes(Type, nullArg) \
487 if (Type##Interp.set(fieldi)) \
489 all##Type##s[fieldi].resize(samplei); \
492 #undef ResizeAllTypes
513 #define DeclareTypeValueSets(Type, nullArg) \
514 UPtrList<const Field<Type>> Type##ValueSets(nValueSets);
516 #undef DeclareTypeValueSets
519 valueSetNames[0] =
"age";
520 scalarValueSets.set(0, &allAges);
524 valueSetNames[fieldi + writeAge_] =
fieldNames[fieldi];
526 #define SetTypeValueSetPtr(Type, nullArg) \
527 if (Type##Interp.set(fieldi)) \
529 Type##ValueSets.set \
531 fieldi + writeAge_, \
532 &all##Type##s[fieldi] \
536 #undef SetTypeValueSetPtr
560 sampledSetPtr_->movePoints();
570 if (&map.
mesh() == &mesh_)
572 sampledSetPtr_->topoChange(map);
582 if (&map.
mesh() == &mesh_)
584 sampledSetPtr_->mapMesh(map);
594 if (&map.
mesh() == &mesh_)
596 sampledSetPtr_->distribute(map);
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.
Macros for easy insertion into run-time selection tables.
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
Generic GeometricField class.
Template class for intrusive linked lists.
void append(const T &)
Append an element at the end of the list.
void size(const label)
Override size to be inconsistent with allocated storage.
Initialise the NamedEnum HashTable from the static list of names.
static void concatenateList(ListType &list)
Gather the given list and concatenate on the master.
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
static bool master(const label communicator=0)
Am I the master process.
static bool & parRun()
Is this a parallel run?
Holds list of sampling positions.
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
A class for handling file names.
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...
Generates streamline data by sampling a set of user-specified fields along a particle track,...
streamlines(const word &name, const Time &runTime, const dictionary &dict)
Construct from Time and dictionary.
virtual wordList fields() const
Return the list of fields required.
virtual void topoChange(const polyTopoChangeMap &)
Update topology using the given map.
virtual void distribute(const polyDistributionMap &)
Redistribute or update using the given distribution map.
virtual ~streamlines()
Destructor.
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
virtual void movePoints(const polyMesh &)
Update for mesh point-motion.
virtual bool execute()
Do nothing.
virtual bool write()
Calculate and write the streamlines.
virtual bool read(const dictionary &)
Read the field average data.
static const NamedEnum< trackDirection, 3 > trackDirectionNames_
Track direction enumeration names.
static const word outputPrefix
Directory prefix.
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
label toGlobal(const label i) const
From local to global.
static autoPtr< interpolation< Type > > New(const word &interpolationType, const VolField< Type > &psi)
Return a reference to the specified interpolation scheme.
Piecewise-linear interpolation method. Uses volPointInterpolation to create values on the points....
Mesh object that implements searches within the local cells and faces.
static const meshSearch & New(const polyMesh &mesh, const pointInCellShapes=pointInCellShapes::tets)
Lookup or construct from mesh and cell decomposition option.
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.
const polyMesh & mesh() const
Return polyMesh.
Mesh consisting of general polyhedral cells.
static word defaultRegion
Return the default region name.
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.
static autoPtr< setWriter > New(const word &writeType, const IOstream::streamFormat writeFormat=IOstream::ASCII, const IOstream::compressionType writeCompression=IOstream::UNCOMPRESSED)
Select given write options.
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.
A class for handling words, derived from string.
static const word null
An empty word.
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
static List< word > fieldNames
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(fvMeshFunctionObject, 0)
addToRunTimeSelectionTable(functionObject, fvModel, dictionary)
errorManipArg< error, int > exit(error &err, const int errNo=1)
List< label > labelList
A List of labels.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
bool mkDir(const fileName &, mode_t=0777)
Make a directory and return an error if it could not be created.
Ostream & endl(Ostream &os)
Add newline and flush stream.
int order(const scalar s)
FOR_ALL_FIELD_TYPES(makeDimensionedPointFieldFunctions)
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
dimensioned< Type > min(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
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,.
void offset(label &lst, const label o)
Ostream & indent(Ostream &os)
Indent stream.
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
#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 ConstructTypeInterpolator(Type, nullArg)
#define RMapAllTypes(Type, nullArg)
#define TypeInterpolatorParameter(Type, nullArg)
#define ShuffleUpAllTypes(Type, nullArg)
#define ConcatenateListAllTypes(Type, nullArg)