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:
@ -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
|
||||
|
||||
|
||||
@ -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:
|
||||
|
||||
|
||||
@ -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]);
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user