mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: streamline : added subcycling
This commit is contained in:
@ -53,16 +53,10 @@ void Foam::streamLine::track()
|
|||||||
initialParticles
|
initialParticles
|
||||||
);
|
);
|
||||||
|
|
||||||
//Pout<< "Seeding particles." << endl;
|
|
||||||
|
|
||||||
const sampledSet& seedPoints = sampledSetPtr_();
|
const sampledSet& seedPoints = sampledSetPtr_();
|
||||||
|
|
||||||
forAll(seedPoints, i)
|
forAll(seedPoints, i)
|
||||||
{
|
{
|
||||||
//Pout<< "Seeded particle at " << seedPoints[i]
|
|
||||||
// << " at cell:" << seedPoints.cells()[i]
|
|
||||||
// << endl;
|
|
||||||
|
|
||||||
particles.addParticle
|
particles.addParticle
|
||||||
(
|
(
|
||||||
new streamLineParticle
|
new streamLineParticle
|
||||||
@ -228,15 +222,14 @@ void Foam::streamLine::track()
|
|||||||
vvInterp,
|
vvInterp,
|
||||||
UIndex, // index of U in vvInterp
|
UIndex, // index of U in vvInterp
|
||||||
trackForward_, // track in +u direction
|
trackForward_, // track in +u direction
|
||||||
|
nSubCycle_, // step through cells in steps?
|
||||||
allTracks_,
|
allTracks_,
|
||||||
allScalars_,
|
allScalars_,
|
||||||
allVectors_
|
allVectors_
|
||||||
);
|
);
|
||||||
|
|
||||||
// Track
|
// Track
|
||||||
//Pout<< "Tracking particles." << endl;
|
|
||||||
particles.move(td);
|
particles.move(td);
|
||||||
//Pout<< "Finished tracking particles." << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -296,6 +289,19 @@ void Foam::streamLine::read(const dictionary& dict)
|
|||||||
UName_ = dict.lookupOrDefault<word>("U", "U");
|
UName_ = dict.lookupOrDefault<word>("U", "U");
|
||||||
dict.lookup("trackForward") >> trackForward_;
|
dict.lookup("trackForward") >> trackForward_;
|
||||||
dict.lookup("lifeTime") >> lifeTime_;
|
dict.lookup("lifeTime") >> lifeTime_;
|
||||||
|
if (lifeTime_ < 1)
|
||||||
|
{
|
||||||
|
FatalErrorIn(":streamLine::read(const dictionary&)")
|
||||||
|
<< "Illegal value " << lifeTime_ << " for lifeTime"
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
dict.lookup("nSubCycle") >> nSubCycle_;
|
||||||
|
if (nSubCycle_ < 1)
|
||||||
|
{
|
||||||
|
nSubCycle_ = 1;
|
||||||
|
}
|
||||||
|
|
||||||
cloudName_ = dict.lookupOrDefault<word>("cloudName", "streamLine");
|
cloudName_ = dict.lookupOrDefault<word>("cloudName", "streamLine");
|
||||||
dict.lookup("seedSampleSet") >> seedSet_;
|
dict.lookup("seedSampleSet") >> seedSet_;
|
||||||
|
|
||||||
@ -323,7 +329,6 @@ void Foam::streamLine::execute()
|
|||||||
{
|
{
|
||||||
// const Time& runTime = const_cast<Time&>(obr_.time());
|
// const Time& runTime = const_cast<Time&>(obr_.time());
|
||||||
// Pout<< "**streamLine::execute : time:" << runTime.timeName() << endl;
|
// Pout<< "**streamLine::execute : time:" << runTime.timeName() << endl;
|
||||||
// Pout<< "**streamLine::execute : time:" << runTime.timeIndex() << endl;
|
|
||||||
//
|
//
|
||||||
// bool isOutputTime = false;
|
// bool isOutputTime = false;
|
||||||
//
|
//
|
||||||
|
|||||||
@ -92,6 +92,9 @@ class streamLine
|
|||||||
//- Maximum lifetime (= number of cells) of particle
|
//- Maximum lifetime (= number of cells) of particle
|
||||||
label lifeTime_;
|
label lifeTime_;
|
||||||
|
|
||||||
|
//- Number of subcycling steps
|
||||||
|
label nSubCycle_;
|
||||||
|
|
||||||
//- Optional specified name of particles
|
//- Optional specified name of particles
|
||||||
word cloudName_;
|
word cloudName_;
|
||||||
|
|
||||||
|
|||||||
@ -36,6 +36,24 @@ namespace Foam
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Estimate dt to cross cell in a few steps
|
||||||
|
Foam::scalar Foam::streamLineParticle::calcSubCycleDeltaT
|
||||||
|
(
|
||||||
|
streamLineParticle::trackData& td,
|
||||||
|
const scalar dt,
|
||||||
|
const vector& U
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
streamLineParticle testParticle(*this);
|
||||||
|
bool oldKeepParticle = td.keepParticle;
|
||||||
|
bool oldSwitchProcessor = td.switchProcessor;
|
||||||
|
scalar fraction = testParticle.trackToFace(position()+dt*U, td);
|
||||||
|
td.keepParticle = oldKeepParticle;
|
||||||
|
td.switchProcessor = oldSwitchProcessor;
|
||||||
|
// Adapt the dt to subdivide the trajectory into 4 substeps.
|
||||||
|
return dt *fraction/td.nSubCycle_;
|
||||||
|
}
|
||||||
|
|
||||||
Foam::vector Foam::streamLineParticle::interpolateFields
|
Foam::vector Foam::streamLineParticle::interpolateFields
|
||||||
(
|
(
|
||||||
const streamLineParticle::trackData& td,
|
const streamLineParticle::trackData& td,
|
||||||
@ -170,14 +188,15 @@ bool Foam::streamLineParticle::move(streamLineParticle::trackData& td)
|
|||||||
&& lifeTime_ > 0
|
&& lifeTime_ > 0
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// TBD: implement subcycling so step through cells in more than
|
|
||||||
// one step.
|
|
||||||
|
|
||||||
// set the lagrangian time-step
|
// set the lagrangian time-step
|
||||||
scalar dt = min(dtMax, tEnd);
|
scalar dt = min(dtMax, tEnd);
|
||||||
|
|
||||||
// Store current position and sampled velocity.
|
// Cross cell in steps
|
||||||
|
for (label subIter = 0; subIter < td.nSubCycle_; subIter++)
|
||||||
|
{
|
||||||
--lifeTime_;
|
--lifeTime_;
|
||||||
|
|
||||||
|
// Store current position and sampled velocity.
|
||||||
sampledPositions_.append(position());
|
sampledPositions_.append(position());
|
||||||
vector U = interpolateFields(td, position(), cell());
|
vector U = interpolateFields(td, position(), cell());
|
||||||
|
|
||||||
@ -186,7 +205,21 @@ bool Foam::streamLineParticle::move(streamLineParticle::trackData& td)
|
|||||||
U = -U;
|
U = -U;
|
||||||
}
|
}
|
||||||
|
|
||||||
dt *= trackToFace(position()+dt*U, td);
|
|
||||||
|
if (subIter == 0 && td.nSubCycle_ > 1)
|
||||||
|
{
|
||||||
|
// Adapt dt to cross cell in a few steps
|
||||||
|
dt = calcSubCycleDeltaT(td, dt, U);
|
||||||
|
}
|
||||||
|
else if (subIter == td.nSubCycle_-1)
|
||||||
|
{
|
||||||
|
// Do full step on last subcycle
|
||||||
|
dt = min(dtMax, tEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
scalar fraction = trackToFace(position()+dt*U, td);
|
||||||
|
dt *= fraction;
|
||||||
|
|
||||||
tEnd -= dt;
|
tEnd -= dt;
|
||||||
stepFraction() = 1.0 - tEnd/deltaT;
|
stepFraction() = 1.0 - tEnd/deltaT;
|
||||||
@ -196,7 +229,14 @@ bool Foam::streamLineParticle::move(streamLineParticle::trackData& td)
|
|||||||
// Force removal
|
// Force removal
|
||||||
lifeTime_ = 0;
|
lifeTime_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!td.keepParticle || td.switchProcessor || lifeTime_ == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!td.keepParticle || lifeTime_ == 0)
|
if (!td.keepParticle || lifeTime_ == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -72,6 +72,7 @@ public:
|
|||||||
const PtrList<interpolationCellPoint<vector> >& vvInterp_;
|
const PtrList<interpolationCellPoint<vector> >& vvInterp_;
|
||||||
const label UIndex_;
|
const label UIndex_;
|
||||||
const bool trackForward_;
|
const bool trackForward_;
|
||||||
|
const label nSubCycle_;
|
||||||
|
|
||||||
DynamicList<vectorList>& allPositions_;
|
DynamicList<vectorList>& allPositions_;
|
||||||
List<DynamicList<scalarList> >& allScalars_;
|
List<DynamicList<scalarList> >& allScalars_;
|
||||||
@ -87,6 +88,7 @@ public:
|
|||||||
const PtrList<interpolationCellPoint<vector> >& vvInterp,
|
const PtrList<interpolationCellPoint<vector> >& vvInterp,
|
||||||
const label UIndex,
|
const label UIndex,
|
||||||
const bool trackForward,
|
const bool trackForward,
|
||||||
|
const label nSubCycle,
|
||||||
DynamicList<List<point> >& allPositions,
|
DynamicList<List<point> >& allPositions,
|
||||||
List<DynamicList<scalarList> >& allScalars,
|
List<DynamicList<scalarList> >& allScalars,
|
||||||
List<DynamicList<vectorList> >& allVectors
|
List<DynamicList<vectorList> >& allVectors
|
||||||
@ -97,6 +99,7 @@ public:
|
|||||||
vvInterp_(vvInterp),
|
vvInterp_(vvInterp),
|
||||||
UIndex_(UIndex),
|
UIndex_(UIndex),
|
||||||
trackForward_(trackForward),
|
trackForward_(trackForward),
|
||||||
|
nSubCycle_(nSubCycle),
|
||||||
allPositions_(allPositions),
|
allPositions_(allPositions),
|
||||||
allScalars_(allScalars),
|
allScalars_(allScalars),
|
||||||
allVectors_(allVectors)
|
allVectors_(allVectors)
|
||||||
@ -123,6 +126,15 @@ private:
|
|||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Estimate dt to cross from current face to next one in nSubCycle
|
||||||
|
// steps.
|
||||||
|
scalar calcSubCycleDeltaT
|
||||||
|
(
|
||||||
|
streamLineParticle::trackData& td,
|
||||||
|
const scalar dt,
|
||||||
|
const vector& U
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Interpolate all quantities; return interpolated velocity.
|
//- Interpolate all quantities; return interpolated velocity.
|
||||||
vector interpolateFields
|
vector interpolateFields
|
||||||
(
|
(
|
||||||
|
|||||||
@ -83,7 +83,10 @@ functions
|
|||||||
fields (p U k);
|
fields (p U k);
|
||||||
|
|
||||||
// Cells particles can travel before being removed
|
// Cells particles can travel before being removed
|
||||||
lifeTime 1000;
|
lifeTime 10000;
|
||||||
|
|
||||||
|
// Number of steps per cell (estimate). Set to 1 to disable subcycling.
|
||||||
|
nSubCycle 5;
|
||||||
|
|
||||||
// Cloud name to use
|
// Cloud name to use
|
||||||
cloudName particleTracks;
|
cloudName particleTracks;
|
||||||
|
|||||||
@ -85,7 +85,10 @@ functions
|
|||||||
fields (p k U);
|
fields (p k U);
|
||||||
|
|
||||||
// Cells particles can travel before being removed
|
// Cells particles can travel before being removed
|
||||||
lifeTime 1000;
|
lifeTime 10000;
|
||||||
|
|
||||||
|
// Number of steps per cell (estimate). Set to 1 to disable subcycling.
|
||||||
|
nSubCycle 5;
|
||||||
|
|
||||||
// Cloud name to use
|
// Cloud name to use
|
||||||
cloudName particleTracks;
|
cloudName particleTracks;
|
||||||
|
|||||||
Reference in New Issue
Block a user