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;
setFormat vtk;
trackForward true;
direction forward; // (forward | backward | bidirectional)
lifeTime 10000;
nSubCycle 5;

View File

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

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2020 OpenCFD Ltd.
Copyright (C) 2015-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -52,13 +52,15 @@ Usage
type streamLine;
libs (fieldFunctionObjects);
// Mandatory entries (runtime modifiable)
U <fieldTrack>;
fields (<fieldTrack> <field1> ... <fieldN>);
setFormat vtk;
direction bidirectional;
lifeTime 10000;
// Optional entries
U <velocity-name>;
direction forward;
cloud particleTracks;
// Mandatory entries (runtime modifiable)
fields (<field1> ... <fieldN>);
setFormat vtk;
lifeTime 10000;
seedSampleSet
{
type uniform;
@ -87,20 +89,20 @@ Usage
Property | Description | Type | Req'd | Dflt
type | Type name: streamLine | 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 | -
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 | -
cloud | Name of cloud | word | yes | -
seedSampleSet| Name of seeding method (see below) | word | yes | -
bounds | Bounding box to trim tracks | vector | no | invertedBox
cloud | Cloud name to use for streamlines | word | no | typeName
seedSampleSet| Seeding description (see below) | dict | yes | -
bounds | Bounding box to trim tracks | vector pair | no | -
trackLength | Tracking segment length | scalar | no | VGREAT
nSubCycle | Number of tracking steps per cell | label | no | 1
interpolationScheme | Interp. scheme for sample | word | no | cellPoint
\endtable
Options for the \c seedSampleSet entry:
Example types for the \c seedSampleSet sub-dict:
\verbatim
uniform | uniform particle seeding
cloud | cloud of points
@ -120,9 +122,9 @@ Usage
Options for the \c direction entry:
\verbatim
bidirectional
forward
backward
bidirectional
\endverbatim
The inherited entries are elaborated in:
@ -147,8 +149,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef functionObjects_streamLine_H
#define functionObjects_streamLine_H
#ifndef Foam_functionObjects_streamLine_H
#define Foam_functionObjects_streamLine_H
#include "streamLineBase.H"
@ -157,6 +159,7 @@ SourceFiles
namespace Foam
{
// Forward Declarations
class objectRegistry;
class dictionary;
@ -169,7 +172,7 @@ namespace functionObjects
class streamLine
:
public streamLineBase
public functionObjects::streamLineBase
{
// 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,
label& UIndex,
PtrList<volScalarField>& vsFlds,
PtrList<interpolation<scalar>>& vsInterp,
PtrList<volVectorField>& vvFlds,
PtrList<interpolation<vector>>& vvInterp
)
{
// Read fields
refPtr<interpolation<vector>> UInterp;
label nScalar = 0;
label nVector = 0;
@ -166,7 +165,7 @@ void Foam::functionObjects::streamLineBase::initInterpolations
else
{
FatalErrorInFunction
<< "Cannot find field " << fieldName << nl
<< "Cannot find scalar/vector field " << fieldName << nl
<< "Valid scalar fields: "
<< flatOutput(mesh_.sortedNames<volScalarField>()) << nl
<< "Valid vector fields: "
@ -174,9 +173,9 @@ void Foam::functionObjects::streamLineBase::initInterpolations
<< exit(FatalError);
}
}
vsInterp.setSize(nScalar);
vsInterp.resize(nScalar);
vvInterp.resize(nVector);
nScalar = 0;
vvInterp.setSize(nVector);
nVector = 0;
for (const word& fieldName : fields_)
@ -186,76 +185,77 @@ void Foam::functionObjects::streamLineBase::initInterpolations
const volScalarField& f = lookupObject<volScalarField>(fieldName);
vsInterp.set
(
nScalar++,
interpolation<scalar>::New
(
interpolationScheme_,
f
)
nScalar,
interpolation<scalar>::New(interpolationScheme_, f)
);
++nScalar;
}
else if (foundObject<volVectorField>(fieldName))
{
const volVectorField& f = lookupObject<volVectorField>(fieldName);
if (f.name() == UName_)
{
UIndex = nVector;
}
vvInterp.set
(
nVector++,
interpolation<vector>::New
(
interpolationScheme_,
f
)
nVector,
interpolation<vector>::New(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
scalarNames_.setSize(vsInterp.size());
scalarNames_.resize(vsInterp.size());
forAll(vsInterp, i)
{
scalarNames_[i] = vsInterp[i].psi().name();
}
vectorNames_.setSize(vvInterp.size());
vectorNames_.resize(vvInterp.size());
forAll(vvInterp, i)
{
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
// ~~~~~~~~~~~~
// Size to maximum expected sizes.
allTracks_.clear();
allTracks_.setCapacity(nSeeds);
allScalars_.setSize(vsInterp.size());
allScalars_.resize(vsInterp.size());
forAll(allScalars_, i)
{
allScalars_[i].clear();
allScalars_[i].setCapacity(nSeeds);
}
allVectors_.setSize(vvInterp.size());
allVectors_.resize(vvInterp.size());
forAll(allVectors_, i)
{
allVectors_[i].clear();
allVectors_[i].setCapacity(nSeeds);
}
return UInterp;
}
@ -877,22 +877,13 @@ bool Foam::functionObjects::streamLineBase::read(const dictionary& dict)
Info<< type() << " " << name() << ":" << nl;
UName_ = dict.getOrDefault<word>("U", "U");
Info<< " Employing velocity field " << UName_ << endl;
if (fields_.empty())
{
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;
if (dict.readIfPresent("trackForward", trackForward))
{
@ -912,7 +903,12 @@ bool Foam::functionObjects::streamLineBase::read(const dictionary& dict)
}
else
{
trackDir_ = trackDirTypeNames.get("direction", dict);
trackDir_ = trackDirTypeNames.getOrDefault
(
"direction",
dict,
trackDirType::FORWARD
);
}
dict.readEntry("lifeTime", lifeTime_);
if (lifeTime_ < 1)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -46,45 +46,7 @@ runTimeModifiable true;
functions
{
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;
}
}
#include "streamLines"
}

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