ENH: streamline improvements

- barycentric coordinates in interpolation (instead of x/y/z)

- ease U (velocity) requirement.
  Needn't be named in the sampled fields.

- default tracking direction is 'forward'
This commit is contained in:
Mark Olesen
2022-07-05 16:01:17 +02:00
parent 71246b94b7
commit f16f3da645
24 changed files with 360 additions and 391 deletions

View File

@ -13,7 +13,7 @@ executeControl writeTime;
writeControl writeTime; writeControl writeTime;
setFormat vtk; setFormat vtk;
trackForward true; direction forward; // (forward | backward | bidirectional)
lifeTime 10000; lifeTime 10000;
nSubCycle 5; nSubCycle 5;

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2015-2020 OpenCFD Ltd. Copyright (C) 2015-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -92,22 +92,14 @@ void Foam::functionObjects::streamLine::track()
Log << " seeded " << nSeeds << " particles" << endl; Log << " seeded " << nSeeds << " particles" << endl;
// Read or lookup fields // Field interpolators
PtrList<volScalarField> vsFlds; // Velocity interpolator
PtrList<interpolation<scalar>> vsInterp; PtrList<interpolation<scalar>> vsInterp;
PtrList<volVectorField> vvFlds;
PtrList<interpolation<vector>> vvInterp; PtrList<interpolation<vector>> vvInterp;
label UIndex = -1; refPtr<interpolation<vector>> UInterp
initInterpolations
( (
nSeeds, initInterpolations(nSeeds, vsInterp, vvInterp)
UIndex,
vsFlds,
vsInterp,
vvFlds,
vvInterp
); );
// Additional particle info // Additional particle info
@ -116,7 +108,7 @@ void Foam::functionObjects::streamLine::track()
particles, particles,
vsInterp, vsInterp,
vvInterp, vvInterp,
UIndex, // index of U in vvInterp UInterp.cref(), // velocity interpolator (possibly within vvInterp)
nSubCycle_, // automatic track control:step through cells in steps? nSubCycle_, // automatic track control:step through cells in steps?
trackLength_, // fixed track length trackLength_, // fixed track length
@ -174,7 +166,6 @@ bool Foam::functionObjects::streamLine::read(const dictionary& dict)
trackLength_ = VGREAT; trackLength_ = VGREAT;
nSubCycle_ = max(nSubCycle_, 1); nSubCycle_ = max(nSubCycle_, 1);
Info<< " automatic track length specified through" Info<< " automatic track length specified through"
<< " number of sub cycles : " << nSubCycle_ << nl << " number of sub cycles : " << nSubCycle_ << nl
<< endl; << endl;

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2020 OpenCFD Ltd. Copyright (C) 2015-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -52,13 +52,15 @@ Usage
type streamLine; type streamLine;
libs (fieldFunctionObjects); libs (fieldFunctionObjects);
// Mandatory entries (runtime modifiable) // Optional entries
U <fieldTrack>; U <velocity-name>;
fields (<fieldTrack> <field1> ... <fieldN>); direction forward;
setFormat vtk;
direction bidirectional;
lifeTime 10000;
cloud particleTracks; cloud particleTracks;
// Mandatory entries (runtime modifiable)
fields (<field1> ... <fieldN>);
setFormat vtk;
lifeTime 10000;
seedSampleSet seedSampleSet
{ {
type uniform; type uniform;
@ -87,20 +89,20 @@ Usage
Property | Description | Type | Req'd | Dflt Property | Description | Type | Req'd | Dflt
type | Type name: streamLine | word | yes | - type | Type name: streamLine | word | yes | -
libs | Library name: fieldFunctionObjects | word | yes | - libs | Library name: fieldFunctionObjects | word | yes | -
U | Name of tracking velocity field | word | yes | - U | Name of tracking velocity field | word | no | U
fields | Names of operand fields to sample | wordList | yes | - fields | Names of operand fields to sample | wordList | yes | -
setFormat | Type of output data | word | yes | - setFormat | Type of output data | word | yes | -
direction | Direction to track | vector | yes | - direction | Direction (enum) to track | word | no | forward
lifetime | Maximum number of particle tracking steps | label | yes | - lifetime | Maximum number of particle tracking steps | label | yes | -
cloud | Name of cloud | word | yes | - cloud | Cloud name to use for streamlines | word | no | typeName
seedSampleSet| Name of seeding method (see below) | word | yes | - seedSampleSet| Seeding description (see below) | dict | yes | -
bounds | Bounding box to trim tracks | vector | no | invertedBox bounds | Bounding box to trim tracks | vector pair | no | -
trackLength | Tracking segment length | scalar | no | VGREAT trackLength | Tracking segment length | scalar | no | VGREAT
nSubCycle | Number of tracking steps per cell | label | no | 1 nSubCycle | Number of tracking steps per cell | label | no | 1
interpolationScheme | Interp. scheme for sample | word | no | cellPoint interpolationScheme | Interp. scheme for sample | word | no | cellPoint
\endtable \endtable
Options for the \c seedSampleSet entry: Example types for the \c seedSampleSet sub-dict:
\verbatim \verbatim
uniform | uniform particle seeding uniform | uniform particle seeding
cloud | cloud of points cloud | cloud of points
@ -120,9 +122,9 @@ Usage
Options for the \c direction entry: Options for the \c direction entry:
\verbatim \verbatim
bidirectional
forward forward
backward backward
bidirectional
\endverbatim \endverbatim
The inherited entries are elaborated in: The inherited entries are elaborated in:
@ -147,8 +149,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef functionObjects_streamLine_H #ifndef Foam_functionObjects_streamLine_H
#define functionObjects_streamLine_H #define Foam_functionObjects_streamLine_H
#include "streamLineBase.H" #include "streamLineBase.H"
@ -157,6 +159,7 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward Declarations
class objectRegistry; class objectRegistry;
class dictionary; class dictionary;
@ -169,7 +172,7 @@ namespace functionObjects
class streamLine class streamLine
: :
public streamLineBase public functionObjects::streamLineBase
{ {
// Private Data // Private Data

View File

@ -139,17 +139,16 @@ Foam::functionObjects::streamLineBase::wallPatch() const
} }
void Foam::functionObjects::streamLineBase::initInterpolations Foam::refPtr<Foam::interpolation<Foam::vector>>
Foam::functionObjects::streamLineBase::initInterpolations
( (
const label nSeeds, const label nSeeds,
label& UIndex,
PtrList<volScalarField>& vsFlds,
PtrList<interpolation<scalar>>& vsInterp, PtrList<interpolation<scalar>>& vsInterp,
PtrList<volVectorField>& vvFlds,
PtrList<interpolation<vector>>& vvInterp PtrList<interpolation<vector>>& vvInterp
) )
{ {
// Read fields refPtr<interpolation<vector>> UInterp;
label nScalar = 0; label nScalar = 0;
label nVector = 0; label nVector = 0;
@ -166,7 +165,7 @@ void Foam::functionObjects::streamLineBase::initInterpolations
else else
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Cannot find field " << fieldName << nl << "Cannot find scalar/vector field " << fieldName << nl
<< "Valid scalar fields: " << "Valid scalar fields: "
<< flatOutput(mesh_.sortedNames<volScalarField>()) << nl << flatOutput(mesh_.sortedNames<volScalarField>()) << nl
<< "Valid vector fields: " << "Valid vector fields: "
@ -174,9 +173,9 @@ void Foam::functionObjects::streamLineBase::initInterpolations
<< exit(FatalError); << exit(FatalError);
} }
} }
vsInterp.setSize(nScalar); vsInterp.resize(nScalar);
vvInterp.resize(nVector);
nScalar = 0; nScalar = 0;
vvInterp.setSize(nVector);
nVector = 0; nVector = 0;
for (const word& fieldName : fields_) for (const word& fieldName : fields_)
@ -186,76 +185,77 @@ void Foam::functionObjects::streamLineBase::initInterpolations
const volScalarField& f = lookupObject<volScalarField>(fieldName); const volScalarField& f = lookupObject<volScalarField>(fieldName);
vsInterp.set vsInterp.set
( (
nScalar++, nScalar,
interpolation<scalar>::New interpolation<scalar>::New(interpolationScheme_, f)
(
interpolationScheme_,
f
)
); );
++nScalar;
} }
else if (foundObject<volVectorField>(fieldName)) else if (foundObject<volVectorField>(fieldName))
{ {
const volVectorField& f = lookupObject<volVectorField>(fieldName); const volVectorField& f = lookupObject<volVectorField>(fieldName);
if (f.name() == UName_)
{
UIndex = nVector;
}
vvInterp.set vvInterp.set
( (
nVector++, nVector,
interpolation<vector>::New interpolation<vector>::New(interpolationScheme_, f)
(
interpolationScheme_,
f
)
); );
if (f.name() == UName_)
{
// Velocity is part of sampled velocity fields
UInterp.cref(vvInterp[nVector]);
}
++nVector;
} }
} }
if (!UInterp)
{
// Velocity was not in sampled velocity fields
UInterp.reset
(
interpolation<vector>::New
(
interpolationScheme_,
// Fatal if missing
lookupObject<volVectorField>(UName_)
)
);
}
// Store the names // Store the names
scalarNames_.setSize(vsInterp.size()); scalarNames_.resize(vsInterp.size());
forAll(vsInterp, i) forAll(vsInterp, i)
{ {
scalarNames_[i] = vsInterp[i].psi().name(); scalarNames_[i] = vsInterp[i].psi().name();
} }
vectorNames_.setSize(vvInterp.size()); vectorNames_.resize(vvInterp.size());
forAll(vvInterp, i) forAll(vvInterp, i)
{ {
vectorNames_[i] = vvInterp[i].psi().name(); vectorNames_[i] = vvInterp[i].psi().name();
} }
// Check that we know the index of U in the interpolators.
if (UIndex == -1)
{
FatalErrorInFunction
<< "Cannot find field to move particles with : " << UName_ << nl
<< "This field has to be present in the sampled fields " << fields_
<< " and in the objectRegistry."
<< exit(FatalError);
}
// Sampled data // Sampled data
// ~~~~~~~~~~~~ // ~~~~~~~~~~~~
// Size to maximum expected sizes. // Size to maximum expected sizes.
allTracks_.clear(); allTracks_.clear();
allTracks_.setCapacity(nSeeds); allTracks_.setCapacity(nSeeds);
allScalars_.setSize(vsInterp.size()); allScalars_.resize(vsInterp.size());
forAll(allScalars_, i) forAll(allScalars_, i)
{ {
allScalars_[i].clear(); allScalars_[i].clear();
allScalars_[i].setCapacity(nSeeds); allScalars_[i].setCapacity(nSeeds);
} }
allVectors_.setSize(vvInterp.size()); allVectors_.resize(vvInterp.size());
forAll(allVectors_, i) forAll(allVectors_, i)
{ {
allVectors_[i].clear(); allVectors_[i].clear();
allVectors_[i].setCapacity(nSeeds); allVectors_[i].setCapacity(nSeeds);
} }
return UInterp;
} }
@ -877,22 +877,13 @@ bool Foam::functionObjects::streamLineBase::read(const dictionary& dict)
Info<< type() << " " << name() << ":" << nl; Info<< type() << " " << name() << ":" << nl;
UName_ = dict.getOrDefault<word>("U", "U"); UName_ = dict.getOrDefault<word>("U", "U");
Info<< " Employing velocity field " << UName_ << endl;
if (fields_.empty()) if (fields_.empty())
{ {
dict.readEntry("fields", fields_); dict.readEntry("fields", fields_);
if (!fields_.found(UName_))
{
FatalIOErrorInFunction(dict)
<< "Velocity field for tracking " << UName_
<< " should be present in the list of fields " << fields_
<< exit(FatalIOError);
}
} }
Info<< " Employing velocity field " << UName_ << endl;
bool trackForward; bool trackForward;
if (dict.readIfPresent("trackForward", trackForward)) if (dict.readIfPresent("trackForward", trackForward))
{ {
@ -912,7 +903,12 @@ bool Foam::functionObjects::streamLineBase::read(const dictionary& dict)
} }
else else
{ {
trackDir_ = trackDirTypeNames.get("direction", dict); trackDir_ = trackDirTypeNames.getOrDefault
(
"direction",
dict,
trackDirType::FORWARD
);
} }
dict.readEntry("lifeTime", lifeTime_); dict.readEntry("lifeTime", lifeTime_);
if (lifeTime_ < 1) if (lifeTime_ < 1)

View File

@ -75,9 +75,9 @@ public:
//- Enumeration defining the track direction //- Enumeration defining the track direction
enum trackDirType : char enum trackDirType : char
{ {
FORWARD, FORWARD, //!< Use "forward" tracking
BACKWARD, BACKWARD, //!< Use "backward" tracking
BIDIRECTIONAL BIDIRECTIONAL, //!< Use "bidirectional" tracking
}; };
//- Names for the trackDir //- Names for the trackDir
@ -104,7 +104,7 @@ protected:
//- Interpolation scheme to use //- Interpolation scheme to use
word interpolationScheme_; word interpolationScheme_;
//- Whether to use +u or -u or both //- Whether to use +U, -U or both
trackDirType trackDir_; trackDirType trackDir_;
//- Maximum lifetime (= number of cells) of particle //- Maximum lifetime (= number of cells) of particle
@ -129,7 +129,7 @@ protected:
wordList vectorNames_; wordList vectorNames_;
// Demand driven // Demand Driven
//- File writer for tracks data //- File writer for tracks data
mutable autoPtr<coordSetWriter> trackWriterPtr_; mutable autoPtr<coordSetWriter> trackWriterPtr_;
@ -159,14 +159,13 @@ protected:
//- Construct patch out of all wall patch faces //- Construct patch out of all wall patch faces
autoPtr<indirectPrimitivePatch> wallPatch() const; autoPtr<indirectPrimitivePatch> wallPatch() const;
//- Initialise fields, interpolators and track storage //- Initialise interpolators and track storage
void initInterpolations // Return velocity interpolator: standalone or part of vector
// interpolators
refPtr<interpolation<vector>> initInterpolations
( (
const label nSeeds, const label nSeeds,
label& UIndex,
PtrList<volScalarField>& vsFlds,
PtrList<interpolation<scalar>>& vsInterp, PtrList<interpolation<scalar>>& vsInterp,
PtrList<volVectorField>& vvFlds,
PtrList<interpolation<vector>>& vvInterp PtrList<interpolation<vector>>& vvInterp
); );

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -35,48 +35,67 @@ License
Foam::vector Foam::streamLineParticle::interpolateFields Foam::vector Foam::streamLineParticle::interpolateFields
( (
const trackingData& td, const trackingData& td,
const point& position, const barycentric& tetCoords,
const label celli, const tetIndices& tetIs
const label facei
) )
{ {
if (celli == -1) if (tetIs.cell() < 0)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Cell:" << celli << abort(FatalError); << "Invalid cell (-1)" << abort(FatalError);
} }
sampledScalars_.setSize(td.vsInterp_.size()); const point position
forAll(td.vsInterp_, scalari) (
tetIs.barycentricToPoint(this->mesh(), tetCoords)
);
bool foundU = false;
vector U(Zero);
// If current position is different
if
(
sampledPositions_.empty()
|| magSqr(sampledPositions_.last() - position) > Foam::sqr(SMALL)
)
{ {
sampledScalars_[scalari].append // Store new location
( sampledPositions_.append(position);
td.vsInterp_[scalari].interpolate
// Scalar fields
sampledScalars_.resize(td.vsInterp_.size());
forAll(td.vsInterp_, i)
{
sampledScalars_[i].append
( (
position, td.vsInterp_[i].interpolate(tetCoords, tetIs, tetIs.face())
celli, );
facei }
)
); // Vector fields
sampledVectors_.resize(td.vvInterp_.size());
forAll(td.vvInterp_, i)
{
sampledVectors_[i].append
(
td.vvInterp_[i].interpolate(tetCoords, tetIs, tetIs.face())
);
if (td.vvInterp_.get(i) == &(td.UInterp_))
{
foundU = true;
U = sampledVectors_[i].last();
}
}
} }
sampledVectors_.setSize(td.vvInterp_.size()); if (!foundU)
forAll(td.vvInterp_, vectori)
{ {
sampledVectors_[vectori].append U = td.UInterp_.interpolate(tetCoords, tetIs, tetIs.face());
(
td.vvInterp_[vectori].interpolate
(
position,
celli,
facei
)
);
} }
const DynamicList<vector>& U = sampledVectors_[td.UIndex_]; return U;
return U.last();
} }
@ -116,12 +135,12 @@ Foam::streamLineParticle::streamLineParticle
>> sampledPositions_ >> sampledScalars >> sampledPositions_ >> sampledScalars
>> sampledVectors; >> sampledVectors;
sampledScalars_.setSize(sampledScalars.size()); sampledScalars_.resize(sampledScalars.size());
forAll(sampledScalars, i) forAll(sampledScalars, i)
{ {
sampledScalars_[i].transfer(sampledScalars[i]); sampledScalars_[i].transfer(sampledScalars[i]);
} }
sampledVectors_.setSize(sampledVectors.size()); sampledVectors_.resize(sampledVectors.size());
forAll(sampledVectors, i) forAll(sampledVectors, i)
{ {
sampledVectors_[i].transfer(sampledVectors[i]); sampledVectors_[i].transfer(sampledVectors[i]);
@ -162,6 +181,7 @@ bool Foam::streamLineParticle::move
while (td.keepParticle && !td.switchProcessor && lifeTime_ > 0) while (td.keepParticle && !td.switchProcessor && lifeTime_ > 0)
{ {
// Set the lagrangian time-step
scalar dt = maxDt; scalar dt = maxDt;
// Cross cell in steps: // Cross cell in steps:
@ -171,16 +191,11 @@ bool Foam::streamLineParticle::move
{ {
--lifeTime_; --lifeTime_;
// Store current position and sampled velocity. // Store current position, return sampled velocity
sampledPositions_.append(position()); vector U =
vector U = interpolateFields(td, position(), cell(), face()); interpolateFields(td, coordinates(), currentTetIndices());
if (!trackForward_) const scalar magU = mag(U);
{
U = -U;
}
scalar magU = mag(U);
if (magU < SMALL) if (magU < SMALL)
{ {
@ -189,6 +204,11 @@ bool Foam::streamLineParticle::move
break; break;
} }
if (!trackForward_)
{
U = -U;
}
U /= magU; U /= magU;
if (td.trackLength_ < GREAT) if (td.trackLength_ < GREAT)
@ -240,8 +260,7 @@ bool Foam::streamLineParticle::move
else else
{ {
// Normal exit. Store last position and fields // Normal exit. Store last position and fields
sampledPositions_.append(position()); (void)interpolateFields(td, coordinates(), currentTetIndices());
interpolateFields(td, position(), cell(), face());
if (debug) if (debug)
{ {
@ -252,21 +271,20 @@ bool Foam::streamLineParticle::move
} }
// Transfer particle data into trackingData. // Transfer particle data into trackingData.
td.allPositions_.append(vectorList()); {
vectorList& top = td.allPositions_.last(); td.allPositions_.append(vectorList());
top.transfer(sampledPositions_); td.allPositions_.last().transfer(sampledPositions_);
}
forAll(sampledScalars_, i) forAll(sampledScalars_, i)
{ {
td.allScalars_[i].append(scalarList()); td.allScalars_[i].append(scalarList());
scalarList& top = td.allScalars_[i].last(); td.allScalars_[i].last().transfer(sampledScalars_[i]);
top.transfer(sampledScalars_[i]);
} }
forAll(sampledVectors_, i) forAll(sampledVectors_, i)
{ {
td.allVectors_[i].append(vectorList()); td.allVectors_[i].append(vectorList());
vectorList& top = td.allVectors_[i].last(); td.allVectors_[i].last().transfer(sampledVectors_[i]);
top.transfer(sampledVectors_[i]);
} }
} }
@ -406,6 +424,7 @@ void Foam::streamLineParticle::writeFields(const Cloud<streamLineParticle>& c)
particle::writeFields(c); particle::writeFields(c);
const label np = c.size(); const label np = c.size();
const bool valid = c.size();
IOField<label> lifeTime IOField<label> lifeTime
( (
@ -426,8 +445,8 @@ void Foam::streamLineParticle::writeFields(const Cloud<streamLineParticle>& c)
++i; ++i;
} }
lifeTime.write(np > 0); lifeTime.write(valid);
sampledPositions.write(np > 0); sampledPositions.write(valid);
} }

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -27,8 +28,8 @@ Class
Foam::streamLineParticle Foam::streamLineParticle
Description Description
Particle class that samples fields as it passes through. Used in streamline Particle class that samples fields as it passes through.
calculation. Used in streamline calculation.
SourceFiles SourceFiles
streamLineParticle.C streamLineParticle.C
@ -70,23 +71,17 @@ public:
{ {
public: public:
// Public data // Public Data
const PtrList<interpolation<scalar>>& vsInterp_; const PtrList<interpolation<scalar>>& vsInterp_;
const PtrList<interpolation<vector>>& vvInterp_;
const interpolation<vector>& UInterp_;
const label nSubCycle_;
const scalar trackLength_;
const PtrList<interpolation<vector>>& vvInterp_; DynamicList<vectorList>& allPositions_;
List<DynamicList<scalarList>>& allScalars_;
const label UIndex_; List<DynamicList<vectorList>>& allVectors_;
const label nSubCycle_;
const scalar trackLength_;
DynamicList<vectorList>& allPositions_;
List<DynamicList<scalarList>>& allScalars_;
List<DynamicList<vectorList>>& allVectors_;
// Constructors // Constructors
@ -97,7 +92,7 @@ public:
streamLineParticleCloud& cloud, streamLineParticleCloud& cloud,
const PtrList<interpolation<scalar>>& vsInterp, const PtrList<interpolation<scalar>>& vsInterp,
const PtrList<interpolation<vector>>& vvInterp, const PtrList<interpolation<vector>>& vvInterp,
const label UIndex, const interpolation<vector>& UInterp,
const label nSubCycle, const label nSubCycle,
const scalar trackLength, const scalar trackLength,
DynamicList<List<point>>& allPositions, DynamicList<List<point>>& allPositions,
@ -108,7 +103,7 @@ public:
particle::trackingData(cloud), particle::trackingData(cloud),
vsInterp_(vsInterp), vsInterp_(vsInterp),
vvInterp_(vvInterp), vvInterp_(vvInterp),
UIndex_(UIndex), UInterp_(UInterp),
nSubCycle_(nSubCycle), nSubCycle_(nSubCycle),
trackLength_(trackLength), trackLength_(trackLength),
allPositions_(allPositions), allPositions_(allPositions),
@ -120,7 +115,7 @@ public:
private: private:
// Private data // Private Data
//- Whether particle transports with +U or -U //- Whether particle transports with +U or -U
bool trackForward_; bool trackForward_;
@ -140,13 +135,12 @@ private:
// Private Member Functions // Private Member Functions
//- Interpolate all quantities; return interpolated velocity. //- Interpolate quantities; return interpolated velocity.
vector interpolateFields vector interpolateFields
( (
const trackingData&, const trackingData& td,
const point&, const barycentric& tetCoords,
const label celli, const tetIndices& tetIs
const label facei
); );
@ -157,7 +151,7 @@ public:
//- Construct from components //- Construct from components
streamLineParticle streamLineParticle
( (
const polyMesh& c, const polyMesh& mesh,
const vector& position, const vector& position,
const label celli, const label celli,
const bool trackForward, const bool trackForward,
@ -167,7 +161,7 @@ public:
//- Construct from Istream //- Construct from Istream
streamLineParticle streamLineParticle
( (
const polyMesh& c, const polyMesh& mesh,
Istream& is, Istream& is,
bool readFields = true, bool readFields = true,
bool newFormat = true bool newFormat = true

View File

@ -34,6 +34,7 @@ namespace Foam
defineTemplateTypeNameAndDebug(Cloud<streamLineParticle>, 0); defineTemplateTypeNameAndDebug(Cloud<streamLineParticle>, 0);
} }
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::streamLineParticleCloud::streamLineParticleCloud Foam::streamLineParticleCloud::streamLineParticleCloud

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -31,12 +31,12 @@ Description
A Cloud of streamLine particles A Cloud of streamLine particles
SourceFiles SourceFiles
streamLineCloud.C streamLineParticleCloud.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef streamLineParticleCloud_H #ifndef Foam_streamLineParticleCloud_H
#define streamLineParticleCloud_H #define Foam_streamLineParticleCloud_H
#include "Cloud.H" #include "Cloud.H"
#include "streamLineParticle.H" #include "streamLineParticle.H"
@ -47,14 +47,20 @@ namespace Foam
{ {
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class streamLineCloud Declaration Class streamLineParticleCloud Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class streamLineParticleCloud class streamLineParticleCloud
: :
public Cloud<streamLineParticle> public Cloud<streamLineParticle>
{ {
// Private Member Functions public:
//- Type of parcel the cloud was instantiated for
typedef streamLineParticle parcelType;
// Generated Methods
//- No copy construct //- No copy construct
streamLineParticleCloud(const streamLineParticleCloud&) = delete; streamLineParticleCloud(const streamLineParticleCloud&) = delete;
@ -63,12 +69,6 @@ class streamLineParticleCloud
void operator=(const streamLineParticleCloud&) = delete; void operator=(const streamLineParticleCloud&) = delete;
public:
//- Type of parcel the cloud was instantiated for
typedef streamLineParticle parcelType;
// Constructors // Constructors
//- Construct given mesh //- Construct given mesh

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2015-2020 OpenCFD Ltd. Copyright (C) 2015-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -231,23 +231,13 @@ void Foam::functionObjects::wallBoundedStreamLine::track()
Log << type() << " : seeded " << nSeeds << " particles." << endl; Log << type() << " : seeded " << nSeeds << " particles." << endl;
// Field interpolators
// Read or lookup fields
PtrList<volScalarField> vsFlds;
PtrList<interpolation<scalar>> vsInterp; PtrList<interpolation<scalar>> vsInterp;
PtrList<volVectorField> vvFlds;
PtrList<interpolation<vector>> vvInterp; PtrList<interpolation<vector>> vvInterp;
label UIndex = -1; refPtr<interpolation<vector>> UInterp
initInterpolations
( (
nSeeds, initInterpolations(nSeeds, vsInterp, vvInterp)
UIndex,
vsFlds,
vsInterp,
vvFlds,
vvInterp
); );
// Additional particle info // Additional particle info
@ -256,7 +246,7 @@ void Foam::functionObjects::wallBoundedStreamLine::track()
particles, particles,
vsInterp, vsInterp,
vvInterp, vvInterp,
UIndex, // index of U in vvInterp UInterp.cref(), // velocity interpolator (possibly within vvInterp)
trackLength_, // fixed track length trackLength_, // fixed track length
isWallPatch, // which faces are to follow isWallPatch, // which faces are to follow

View File

@ -52,13 +52,15 @@ Usage
type wallBoundedStreamLine; type wallBoundedStreamLine;
libs (fieldFunctionObjects); libs (fieldFunctionObjects);
// Mandatory entries (runtime modifiable) // Optional entries
U <fieldTrack>; U <velocity-name>;
fields (<fieldTrack> <field1> ... <fieldN>); direction forward;
setFormat vtk;
direction bidirectional;
lifeTime 10000;
cloud particleTracks; cloud particleTracks;
// Mandatory entries (runtime modifiable)
fields (<field1> ... <fieldN>);
setFormat vtk;
lifeTime 10000;
seedSampleSet seedSampleSet
{ {
type patchSeed; type patchSeed;
@ -89,17 +91,17 @@ Usage
U | Name of tracking velocity field | word | yes | - U | Name of tracking velocity field | word | yes | -
fields | Names of operand fields to sample | wordList | yes | - fields | Names of operand fields to sample | wordList | yes | -
setFormat | Type of output data | word | yes | - setFormat | Type of output data | word | yes | -
direction | Direction to track | vector | yes | - direction | Direction (enum) to track | word | no | forward
lifetime | Maximum number of particle tracking steps | label | yes | - lifetime | Maximum number of particle tracking steps | label | yes | -
cloud | Name of cloud | word | yes | - cloud | Cloud name to use for streamlines | word | no | typeName
seedSampleSet| Name of seeding method (see below) | word | yes | - seedSampleSet| Seeding description (see below) | dict | yes | -
bounds | Bounding box to trim tracks | vector | no | invertedBox bounds | Bounding box to trim tracks | vector pair | no | -
trackLength | Tracking segment length | scalar | no | VGREAT trackLength | Tracking segment length | scalar | no | VGREAT
nSubCycle | Number of tracking steps per cell | label | no | 1 nSubCycle | Number of tracking steps per cell | label | no | 1
interpolationScheme | Interp. scheme for sample | word | no | cellPoint interpolationScheme | Interp. scheme for sample | word | no | cellPoint
\endtable \endtable
Options for the \c seedSampleSet entry: Example types for the \c seedSampleSet sub-dict:
\verbatim \verbatim
uniform | uniform particle seeding uniform | uniform particle seeding
cloud | cloud of points cloud | cloud of points
@ -120,9 +122,9 @@ Usage
Options for the \c direction entry: Options for the \c direction entry:
\verbatim \verbatim
bidirectional
forward forward
backward backward
bidirectional
\endverbatim \endverbatim
The inherited entries are elaborated in: The inherited entries are elaborated in:
@ -144,8 +146,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef functionObjects_wallBoundedStreamLine_H #ifndef Foam_functionObjects_wallBoundedStreamLine_H
#define functionObjects_wallBoundedStreamLine_H #define Foam_functionObjects_wallBoundedStreamLine_H
#include "streamLineBase.H" #include "streamLineBase.H"
@ -153,7 +155,6 @@ SourceFiles
namespace Foam namespace Foam
{ {
namespace functionObjects namespace functionObjects
{ {
@ -163,7 +164,7 @@ namespace functionObjects
class wallBoundedStreamLine class wallBoundedStreamLine
: :
public streamLineBase public functionObjects::streamLineBase
{ {
protected: protected:

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd. Copyright (C) 2017-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -39,53 +39,57 @@ Foam::vector Foam::wallBoundedStreamLineParticle::interpolateFields
const label facei const label facei
) )
{ {
if (celli == -1) if (celli < 0)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Cell:" << celli << abort(FatalError); << "Invalid cell (-1)" << abort(FatalError);
} }
const vector U = bool foundU = false;
td.vvInterp_[td.UIndex_].interpolate(position, celli, facei); vector U(Zero);
// Check if at different position // If current position is different
if if
( (
!sampledPositions_.size() sampledPositions_.empty()
|| magSqr(sampledPositions_.last() - position) > Foam::sqr(SMALL) || magSqr(sampledPositions_.last() - position) > Foam::sqr(SMALL)
) )
{ {
// Store the location // Store new location
sampledPositions_.append(position); sampledPositions_.append(position);
// Store the scalar fields // Scalar fields
sampledScalars_.setSize(td.vsInterp_.size()); sampledScalars_.resize(td.vsInterp_.size());
forAll(td.vsInterp_, scalari) forAll(td.vsInterp_, i)
{ {
sampledScalars_[scalari].append sampledScalars_[i].append
( (
td.vsInterp_[scalari].interpolate(position, celli, facei) td.vsInterp_[i].interpolate(position, celli, facei)
); );
} }
// Store the vector fields // Vector fields
sampledVectors_.setSize(td.vvInterp_.size()); sampledVectors_.resize(td.vvInterp_.size());
forAll(td.vvInterp_, vectori) forAll(td.vvInterp_, i)
{ {
vector positionU; sampledVectors_[i].append
if (vectori == td.UIndex_) (
td.vvInterp_[i].interpolate(position, celli, facei)
);
if (td.vvInterp_.get(i) == &(td.UInterp_))
{ {
positionU = U; foundU = true;
U = sampledVectors_[i].last();
} }
else
{
positionU =
td.vvInterp_[vectori].interpolate(position, celli, facei);
}
sampledVectors_[vectori].append(positionU);
} }
} }
if (!foundU)
{
U = td.UInterp_.interpolate(position, celli, facei);
}
return U; return U;
} }
@ -97,12 +101,7 @@ Foam::vector Foam::wallBoundedStreamLineParticle::sample
{ {
vector U = interpolateFields(td, localPosition_, cell(), face()); vector U = interpolateFields(td, localPosition_, cell(), face());
if (!trackForward_) const scalar magU = mag(U);
{
U = -U;
}
scalar magU = mag(U);
if (magU < SMALL) if (magU < SMALL)
{ {
@ -110,10 +109,13 @@ Foam::vector Foam::wallBoundedStreamLineParticle::sample
lifeTime_ = 0; lifeTime_ = 0;
return vector::zero; return vector::zero;
} }
else
if (!trackForward_)
{ {
return U/magU; U = -U;
} }
return U/magU;
} }
@ -165,12 +167,12 @@ Foam::wallBoundedStreamLineParticle::wallBoundedStreamLineParticle
is >> trackForward_ >> lifeTime_ is >> trackForward_ >> lifeTime_
>> sampledPositions_ >> sampledScalars >> sampledVectors; >> sampledPositions_ >> sampledScalars >> sampledVectors;
sampledScalars_.setSize(sampledScalars.size()); sampledScalars_.resize(sampledScalars.size());
forAll(sampledScalars, i) forAll(sampledScalars, i)
{ {
sampledScalars_[i].transfer(sampledScalars[i]); sampledScalars_[i].transfer(sampledScalars[i]);
} }
sampledVectors_.setSize(sampledVectors.size()); sampledVectors_.resize(sampledVectors.size());
forAll(sampledVectors, i) forAll(sampledVectors, i)
{ {
sampledVectors_[i].transfer(sampledVectors[i]); sampledVectors_[i].transfer(sampledVectors[i]);

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd. Copyright (C) 2017-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -74,9 +74,11 @@ public:
{ {
public: public:
// Public Data
const PtrList<interpolation<scalar>>& vsInterp_; const PtrList<interpolation<scalar>>& vsInterp_;
const PtrList<interpolation<vector>>& vvInterp_; const PtrList<interpolation<vector>>& vvInterp_;
const label UIndex_; const interpolation<vector>& UInterp_;
const scalar trackLength_; const scalar trackLength_;
DynamicList<vectorList>& allPositions_; DynamicList<vectorList>& allPositions_;
@ -92,7 +94,7 @@ public:
TrackCloudType& cloud, TrackCloudType& cloud,
const PtrList<interpolation<scalar>>& vsInterp, const PtrList<interpolation<scalar>>& vsInterp,
const PtrList<interpolation<vector>>& vvInterp, const PtrList<interpolation<vector>>& vvInterp,
const label UIndex, const interpolation<vector>& UInterp,
const scalar trackLength, const scalar trackLength,
const bitSet& isWallPatch, const bitSet& isWallPatch,
@ -104,7 +106,7 @@ public:
wallBoundedParticle::trackingData(cloud, isWallPatch), wallBoundedParticle::trackingData(cloud, isWallPatch),
vsInterp_(vsInterp), vsInterp_(vsInterp),
vvInterp_(vvInterp), vvInterp_(vvInterp),
UIndex_(UIndex), UInterp_(UInterp),
trackLength_(trackLength), trackLength_(trackLength),
allPositions_(allPositions), allPositions_(allPositions),

View File

@ -35,8 +35,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef wallBoundedStreamLineParticleCloud_H #ifndef Foam_wallBoundedStreamLineParticleCloud_H
#define wallBoundedStreamLineParticleCloud_H #define Foam_wallBoundedStreamLineParticleCloud_H
#include "Cloud.H" #include "Cloud.H"
#include "wallBoundedStreamLineParticle.H" #include "wallBoundedStreamLineParticle.H"
@ -54,7 +54,13 @@ class wallBoundedStreamLineParticleCloud
: :
public Cloud<wallBoundedStreamLineParticle> public Cloud<wallBoundedStreamLineParticle>
{ {
// Private Member Functions public:
//- Type of parcel the cloud was instantiated for
typedef wallBoundedStreamLineParticle parcelType;
// Generated Methods
//- No copy construct //- No copy construct
wallBoundedStreamLineParticleCloud wallBoundedStreamLineParticleCloud
@ -66,12 +72,6 @@ class wallBoundedStreamLineParticleCloud
void operator=(const wallBoundedStreamLineParticleCloud&) = delete; void operator=(const wallBoundedStreamLineParticleCloud&) = delete;
public:
//- Type of parcel the cloud was instantiated for
typedef wallBoundedStreamLineParticle parcelType;
// Constructors // Constructors
//- Construct given mesh //- Construct given mesh

View File

@ -36,9 +36,7 @@ bool Foam::wallBoundedStreamLineParticle::move
const scalar trackTime const scalar trackTime
) )
{ {
typename TrackCloudType::particleType& p = auto& p = static_cast<typename TrackCloudType::particleType&>(*this);
static_cast<typename TrackCloudType::particleType&>(*this);
// Check position is inside tet // Check position is inside tet
//checkInside(); //checkInside();
@ -49,14 +47,9 @@ bool Foam::wallBoundedStreamLineParticle::move
scalar tEnd = (1.0 - stepFraction())*trackTime; scalar tEnd = (1.0 - stepFraction())*trackTime;
scalar maxDt = mesh().bounds().mag(); scalar maxDt = mesh().bounds().mag();
while while (td.keepParticle && !td.switchProcessor && lifeTime_ > 0)
(
td.keepParticle
&& !td.switchProcessor
&& lifeTime_ > 0
)
{ {
// set the lagrangian time-step // Set the lagrangian time-step
scalar dt = maxDt; scalar dt = maxDt;
--lifeTime_; --lifeTime_;
@ -124,25 +117,19 @@ bool Foam::wallBoundedStreamLineParticle::move
// Transfer particle data into trackingData. // Transfer particle data into trackingData.
{ {
//td.allPositions_.append(sampledPositions_);
td.allPositions_.append(vectorList()); td.allPositions_.append(vectorList());
vectorList& top = td.allPositions_.last(); td.allPositions_.last().transfer(sampledPositions_);
top.transfer(sampledPositions_);
} }
forAll(sampledScalars_, i) forAll(sampledScalars_, i)
{ {
//td.allScalars_[i].append(sampledScalars_[i]);
td.allScalars_[i].append(scalarList()); td.allScalars_[i].append(scalarList());
scalarList& top = td.allScalars_[i].last(); td.allScalars_[i].last().transfer(sampledScalars_[i]);
top.transfer(sampledScalars_[i]);
} }
forAll(sampledVectors_, i) forAll(sampledVectors_, i)
{ {
//td.allVectors_[i].append(sampledVectors_[i]);
td.allVectors_[i].append(vectorList()); td.allVectors_[i].append(vectorList());
vectorList& top = td.allVectors_[i].last(); td.allVectors_[i].last().transfer(sampledVectors_[i]);
top.transfer(sampledVectors_[i]);
} }
} }

View File

@ -3,7 +3,7 @@
nLines 24; nLines 24;
start (0 0.5 0); start (0 0.5 0);
end (9 0.5 0); end (9 0.5 0);
fields (U); fields (p);
#includeEtc "caseDicts/postProcessing/visualization/streamlines.cfg" #includeEtc "caseDicts/postProcessing/visualization/streamlines.cfg"

View File

@ -13,25 +13,22 @@ streamLines
// Time control etc // Time control etc
${_visualization}; ${_visualization};
setFormat vtk; setFormat vtk;
// Velocity field to use for tracking. // Tracking direction (forward | backward | bidirectional)
U U; direction forward;
// Tracked forwards (+U) or backwards (-U) // Fields to sample
trackForward true; fields (p U);
// Names of fields to sample. Should contain above velocity field!
fields (p U);
// Steps particles can travel before being removed // Steps particles can travel before being removed
lifeTime 10000; lifeTime 10000;
// Number of steps per cell (estimate). Set to 1 to disable subcycling. // Number of steps per cell (estimate). Set to 1 to disable subcycling.
nSubCycle 5; nSubCycle 5;
// Cloud name to use // Cloud name to use
cloud particleTracks; cloud particleTracks;
// Seeding method. // Seeding method.
seedSampleSet seedSampleSet

View File

@ -13,25 +13,22 @@ streamLines
// Time control etc // Time control etc
${_visualization}; ${_visualization};
setFormat vtk; // csv | raw | gnuplot | ensight | xmgr setFormat vtk;
// Velocity field to use for tracking. // Tracking direction (forward | backward | bidirectional)
U U; direction forward;
// Tracked forwards (+U) or backwards (-U) // Fields to sample
trackForward true; fields (p U);
// Names of fields to sample. Should contain above velocity field!
fields (p U);
// Steps particles can travel before being removed // Steps particles can travel before being removed
lifeTime 10000; lifeTime 10000;
// Number of steps per cell (estimate). Set to 1 to disable subcycling. // Number of steps per cell (estimate). Set to 1 to disable subcycling.
nSubCycle 5; nSubCycle 5;
// Cloud name to use // Cloud name to use
cloud particleTracks; cloud particleTracks;
// Seeding method. // Seeding method.
seedSampleSet seedSampleSet

View File

@ -32,9 +32,6 @@ streamLine1
nSubCycle 1; nSubCycle 1;
interpolationScheme cellPoint; interpolationScheme cellPoint;
// Deprecated
// trackForward true;
// Optional (inherited) entries // Optional (inherited) entries
region region0; region region0;
enabled true; enabled true;

View File

@ -8,38 +8,35 @@
streamLines streamLines
{ {
// Where to load it from type streamLine;
libs (fieldFunctionObjects); libs (fieldFunctionObjects);
type streamLine;
// Output every // Output every
writeControl writeTime; writeControl writeTime;
// writeInterval 10; // writeInterval 10;
setFormat vtk; // csv | raw | gnuplot | ensight setFormat vtk;
// Tracked forwards (+U) or backwards (-U) // Tracking direction (forward | backward | bidirectional)
trackForward true; direction forward;
// Names of fields to sample. Should contain above velocity field! // Fields to sample
fields (p U k); fields (p U k);
// Steps particles can travel before being removed // Steps particles can travel before being removed
lifeTime 10000; lifeTime 10000;
//- Specify either absolute length of steps (trackLength) or a number //- Specify either absolute length of steps (trackLength) or a number
// of subcycling steps per cell (nSubCycle) // of subcycling steps per cell (nSubCycle)
// Size of single track segment [m] // Size of single track segment [m]
//trackLength 1e-3; //trackLength 1e-3;
// Number of steps per cell (estimate). Set to 1 to disable subcycling.
nSubCycle 5;
// Number of steps per cell (estimate). Set to 1 to disable subcycling.
nSubCycle 5;
// Cloud name to use // Cloud name to use
cloud particleTracks; cloud particleTracks;
// Seeding method. // Seeding method.
seedSampleSet seedSampleSet

View File

@ -9,10 +9,8 @@
// Interpolate U to create near-wall UNear // Interpolate U to create near-wall UNear
near near
{ {
// Where to load it from type nearWallFields;
libs (fieldFunctionObjects); libs (fieldFunctionObjects);
type nearWallFields;
// Output every // Output every
writeControl writeTime; writeControl writeTime;
@ -39,15 +37,16 @@ near
// Use UNear to track along wall // Use UNear to track along wall
wallBoundedStreamLines wallBoundedStreamLines
{ {
// Mandatory entries type wallBoundedStreamLine;
type wallBoundedStreamLine; libs (fieldFunctionObjects);
libs (fieldFunctionObjects);
U UNear; // Velocity field to use for tracking. U UNear; // Velocity field for tracking
fields (p U k UNear); // Names of fields to sample. fields (p U k UNear); // Fields to sample
setFormat vtk; // raw | gnuplot | xmgr setFormat vtk;
direction forward; direction forward;
lifeTime 100; // Steps particles can travel before being removed lifeTime 100; // Steps particles can travel before being removed
cloud wallBoundedParticleTracks; cloud wallBoundedParticleTracks;
seedSampleSet seedSampleSet
{ {
type patchSeed; type patchSeed;
@ -80,9 +79,6 @@ wallBoundedStreamLines
// nSubCycle 1; // nSubCycle 1;
interpolationScheme cellPoint; interpolationScheme cellPoint;
// Deprecated
// trackForward true;
// Optional (inherited) entries // Optional (inherited) entries
region region0; region region0;
enabled true; enabled true;

View File

@ -46,45 +46,7 @@ runTimeModifiable true;
functions functions
{ {
streamLines #include "streamLines"
{
type streamLine;
// Where to load it from (if not already in solver)
libs (fieldFunctionObjects);
// Output every
writeControl writeTime;
// writeInterval 10;
setFormat vtk; // csv | raw | gnuplot | ensight | xmgr
// Tracked forwards (+U) or backwards (-U)
trackForward true;
// Names of fields to sample. Should contain above velocity field!
fields (p k U);
// Steps particles can travel before being removed
lifeTime 10000;
// Number of steps per cell (estimate). Set to 1 to disable subcycling.
nSubCycle 5;
// Cloud name to use
cloud particleTracks;
// Seeding method.
seedSampleSet
{
type uniform;
axis x; //distance;
start (-0.0205 0.001 0.00001);
end (-0.0205 0.0251 0.00001);
nPoints 10;
}
}
} }

View File

@ -0,0 +1,41 @@
// -*- C++ -*-
streamLines
{
type streamLine;
libs (fieldFunctionObjects);
writeControl writeTime;
// writeInterval 10;
setFormat vtk;
// Tracking direction (forward | backward | bidirectional)
direction forward;
// Fields to sample
fields (p k U);
// Steps particles can travel before being removed
lifeTime 10000;
// Number of steps per cell (estimate). Set to 1 to disable subcycling.
nSubCycle 5;
// Cloud name to use
cloud particleTracks;
// Seeding method.
seedSampleSet
{
type uniform;
axis x; //distance;
start (-0.0205 0.001 0.00001);
end (-0.0205 0.0251 0.00001);
nPoints 10;
}
}
// ************************************************************************* //

View File

@ -9,25 +9,22 @@ streamLines
// Time control etc // Time control etc
${_visualization}; ${_visualization};
setFormat vtk; setFormat vtk;
// Velocity field to use for tracking. // Tracking direction (forward | backward | bidirectional)
U U; direction forward;
// Tracked forwards (+U) or backwards (-U) // Fields to sample
trackForward true; fields (p U);
// Names of fields to sample. Should contain above velocity field!
fields (p U);
// Steps particles can travel before being removed // Steps particles can travel before being removed
lifeTime 10000; lifeTime 10000;
// Number of steps per cell (estimate). Set to 1 to disable subcycling. // Number of steps per cell (estimate). Set to 1 to disable subcycling.
nSubCycle 5; nSubCycle 5;
// Cloud name to use // Cloud name to use
cloud particleTracks; cloud particleTracks;
// Seeding method. // Seeding method.
seedSampleSet seedSampleSet