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

@ -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]);
}
}