From aa4cb44b1e38f70c4eb0e031a5bcf0dbcb8644c6 Mon Sep 17 00:00:00 2001 From: Will Bainbridge Date: Fri, 20 Jul 2018 16:16:50 +0100 Subject: [PATCH] streamLines: Write out the streamline age The streamLines function object now writes out "age" by default. This is calculated as the total integration time from the starting point of the streamline. This value can be negative if tracking is performed in the reverse direction. Writing "age" can be deactivated by means of a "writeAge no;" entry in the function object specification. --- .../field/streamLine/streamLine.C | 85 +++++++++++++------ .../field/streamLine/streamLine.H | 12 ++- .../field/streamLine/streamLineParticle.C | 53 +++++++++--- .../field/streamLine/streamLineParticle.H | 10 +++ 4 files changed, 122 insertions(+), 38 deletions(-) diff --git a/src/functionObjects/field/streamLine/streamLine.C b/src/functionObjects/field/streamLine/streamLine.C index c55b9289b1..e40df1b8bd 100644 --- a/src/functionObjects/field/streamLine/streamLine.C +++ b/src/functionObjects/field/streamLine/streamLine.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -244,6 +244,8 @@ void Foam::functionObjects::streamLine::track() // Size to maximum expected sizes. allTracks_.clear(); allTracks_.setCapacity(nSeeds); + allAges_.clear(); + allAges_.setCapacity(nSeeds); allScalars_.setSize(vsInterp.size()); forAll(allScalars_, i) { @@ -272,6 +274,7 @@ void Foam::functionObjects::streamLine::track() trackLength_, // fixed track length allTracks_, + allAges_, allScalars_, allVectors_ ); @@ -342,6 +345,8 @@ bool Foam::functionObjects::streamLine::read(const dictionary& dict) << exit(FatalIOError); } + writeAge_ = dict.lookupOrDefault("writeAge", true); + // The trackForward entry is maintained here for backwards compatibility if (!dict.found("direction") && dict.found("trackForward")) { @@ -498,9 +503,9 @@ bool Foam::functionObjects::streamLine::write() ); // Distribute the scalars - forAll(allScalars_, scalarI) + forAll(allScalars_, scalari) { - allScalars_[scalarI].shrink(); + allScalars_[scalari].shrink(); mapDistributeBase::distribute ( Pstream::commsTypes::scheduled, @@ -510,15 +515,15 @@ bool Foam::functionObjects::streamLine::write() false, distMap.constructMap(), false, - allScalars_[scalarI], + allScalars_[scalari], flipOp() ); - allScalars_[scalarI].setCapacity(allScalars_[scalarI].size()); + allScalars_[scalari].setCapacity(allScalars_[scalari].size()); } // Distribute the vectors - forAll(allVectors_, vectorI) + forAll(allVectors_, vectori) { - allVectors_[vectorI].shrink(); + allVectors_[vectori].shrink(); mapDistributeBase::distribute ( Pstream::commsTypes::scheduled, @@ -528,10 +533,10 @@ bool Foam::functionObjects::streamLine::write() false, distMap.constructMap(), false, - allVectors_[vectorI], + allVectors_[vectori], flipOp() ); - allVectors_[vectorI].setCapacity(allVectors_[vectorI].size()); + allVectors_[vectori].setCapacity(allVectors_[vectori].size()); } } @@ -587,21 +592,46 @@ bool Foam::functionObjects::streamLine::write() // Convert scalar values - if (allScalars_.size() > 0) + if (allScalars_.size() > 0 || writeAge_) { - List> scalarValues(allScalars_.size()); + List> ageAndScalarValues + ( + allScalars_.size() + writeAge_ + ); + wordList ageAndScalarNames(allScalars_.size() + writeAge_); - forAll(allScalars_, scalarI) + if (writeAge_) { - DynamicList& allTrackVals = - allScalars_[scalarI]; - scalarValues[scalarI].setSize(allTrackVals.size()); + DynamicList& allTrackAges = allAges_; + ageAndScalarValues[0].setSize(allTrackAges.size()); + forAll(allTrackAges, trackI) + { + ageAndScalarValues[0][trackI].transfer + ( + allTrackAges[trackI] + ); + } + + ageAndScalarNames[0] = "age"; + } + + forAll(allScalars_, scalari) + { + const label ageAndScalari = scalari + writeAge_; + + DynamicList& allTrackVals = allScalars_[scalari]; + + ageAndScalarValues[ageAndScalari].setSize(allTrackVals.size()); forAll(allTrackVals, trackI) { - scalarList& trackVals = allTrackVals[trackI]; - scalarValues[scalarI][trackI].transfer(trackVals); + ageAndScalarValues[ageAndScalari][trackI].transfer + ( + allTrackVals[trackI] + ); } + + ageAndScalarNames[ageAndScalari] = scalarNames_[scalari]; } fileName vtkFile @@ -610,7 +640,7 @@ bool Foam::functionObjects::streamLine::write() / scalarFormatterPtr_().getFileName ( tracks[0], - scalarNames_ + ageAndScalarNames ) ); @@ -620,8 +650,8 @@ bool Foam::functionObjects::streamLine::write() ( true, // writeTracks tracks, - scalarNames_, - scalarValues, + ageAndScalarNames, + ageAndScalarValues, OFstream(vtkFile)() ); } @@ -632,16 +662,17 @@ bool Foam::functionObjects::streamLine::write() { List> vectorValues(allVectors_.size()); - forAll(allVectors_, vectorI) + forAll(allVectors_, vectori) { - DynamicList& allTrackVals = - allVectors_[vectorI]; - vectorValues[vectorI].setSize(allTrackVals.size()); + DynamicList& allTrackVals = allVectors_[vectori]; + vectorValues[vectori].setSize(allTrackVals.size()); forAll(allTrackVals, trackI) { - vectorList& trackVals = allTrackVals[trackI]; - vectorValues[vectorI][trackI].transfer(trackVals); + vectorValues[vectori][trackI].transfer + ( + allTrackVals[trackI] + ); } } @@ -655,6 +686,8 @@ bool Foam::functionObjects::streamLine::write() ) ); + Info<< " Writing data to " << vtkFile.path() << endl; + vectorFormatterPtr_().write ( true, // writeTracks diff --git a/src/functionObjects/field/streamLine/streamLine.H b/src/functionObjects/field/streamLine/streamLine.H index 975f58f2ec..b9c52a70fd 100644 --- a/src/functionObjects/field/streamLine/streamLine.H +++ b/src/functionObjects/field/streamLine/streamLine.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -39,7 +39,7 @@ Description setFormat vtk; U U; - trackForward yes; + direction both; fields ( @@ -69,7 +69,9 @@ Usage type | Type name: streamLine | yes | setFormat | Output data type | yes | U | Tracking velocity field name | no | U + direction | Direction in which to track | yes | fields | Fields to sample | yes | + writeTime | Write the flow time along the streamline | no | no lifetime | Maximum number of particle tracking steps | yes | trackLength | Tracking segment length | no | nSubCycle | Number of tracking steps per cell | no| @@ -187,6 +189,9 @@ private: //- Names of vector fields wordList vectorNames_; + //- Write the streamline ages + Switch writeAge_; + // Demand driven @@ -211,6 +216,9 @@ private: //- All tracks. Per particle the points it passed through DynamicList> allTracks_; + //- All ages. Per particle the age when it passed through the points + DynamicList> allAges_; + //- Per scalarField, per particle, the sampled value. List> allScalars_; diff --git a/src/functionObjects/field/streamLine/streamLineParticle.C b/src/functionObjects/field/streamLine/streamLineParticle.C index eb463a1582..7dd0c2daba 100644 --- a/src/functionObjects/field/streamLine/streamLineParticle.C +++ b/src/functionObjects/field/streamLine/streamLineParticle.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -26,6 +26,7 @@ License #include "streamLineParticle.H" #include "streamLineParticleCloud.H" #include "vectorFieldIOField.H" +#include "scalarFieldIOField.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -88,7 +89,8 @@ Foam::streamLineParticle::streamLineParticle ) : particle(mesh, position, celli), - lifeTime_(lifeTime) + lifeTime_(lifeTime), + age_(0) {} @@ -106,8 +108,8 @@ Foam::streamLineParticle::streamLineParticle List sampledScalars; List sampledVectors; - is >> lifeTime_ >> sampledPositions_ >> sampledScalars - >> sampledVectors; + is >> lifeTime_ >> age_ >> sampledPositions_ >> sampledTimes_ + >> sampledScalars >> sampledVectors; sampledScalars_.setSize(sampledScalars.size()); forAll(sampledScalars, i) @@ -137,8 +139,11 @@ Foam::streamLineParticle::streamLineParticle : particle(p), lifeTime_(p.lifeTime_), + age_(p.age_), sampledPositions_(p.sampledPositions_), - sampledScalars_(p.sampledScalars_) + sampledTimes_(p.sampledTimes_), + sampledScalars_(p.sampledScalars_), + sampledVectors_(p.sampledVectors_) {} @@ -169,6 +174,7 @@ bool Foam::streamLineParticle::move // Store current position and sampled velocity. sampledPositions_.append(position()); + sampledTimes_.append(age_); vector U = interpolateFields(td, position(), cell(), face()); if (!td.trackForward_) @@ -205,7 +211,10 @@ bool Foam::streamLineParticle::move dt = maxDt; } - trackToAndHitFace(dt*U, 0, cloud, td); + age_ += + (td.trackForward_ ? +1 : -1) + *dt + *(1 - trackToAndHitFace(dt*U, 0, cloud, td)); if ( @@ -237,6 +246,7 @@ bool Foam::streamLineParticle::move { // Normal exit. Store last position and fields sampledPositions_.append(position()); + sampledTimes_.append(age_); interpolateFields(td, position(), cell(), face()); if (debug) @@ -248,10 +258,16 @@ 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()); + vectorList& top = td.allPositions_.last(); + top.transfer(sampledPositions_); + } + { + td.allTimes_.append(scalarList()); + scalarList& top = td.allTimes_.last(); + top.transfer(sampledTimes_); + } forAll(sampledScalars_, i) { td.allScalars_[i].append(scalarList()); @@ -406,11 +422,19 @@ void Foam::streamLineParticle::readFields(Cloud& c) ); c.checkFieldIOobject(c, sampledPositions); + scalarFieldIOField sampledTimes + ( + c.fieldIOobject("sampledTimes", IOobject::MUST_READ), + valid + ); + c.checkFieldIOobject(c, sampledTimes); + label i = 0; forAllIter(Cloud, c, iter) { iter().lifeTime_ = lifeTime[i]; iter().sampledPositions_.transfer(sampledPositions[i]); + iter().sampledTimes_.transfer(sampledTimes[i]); i++; } } @@ -432,17 +456,24 @@ void Foam::streamLineParticle::writeFields(const Cloud& c) c.fieldIOobject("sampledPositions", IOobject::NO_READ), np ); + scalarFieldIOField sampledTimes + ( + c.fieldIOobject("sampledTimes", IOobject::NO_READ), + np + ); label i = 0; forAllConstIter(Cloud, c, iter) { lifeTime[i] = iter().lifeTime_; sampledPositions[i] = iter().sampledPositions_; + sampledTimes[i] = iter().sampledTimes_; i++; } lifeTime.write(np > 0); sampledPositions.write(np > 0); + sampledTimes.write(np > 0); } @@ -452,7 +483,9 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const streamLineParticle& p) { os << static_cast(p) << token::SPACE << p.lifeTime_ + << token::SPACE << p.age_ << token::SPACE << p.sampledPositions_ + << token::SPACE << p.sampledTimes_ << token::SPACE << p.sampledScalars_ << token::SPACE << p.sampledVectors_; diff --git a/src/functionObjects/field/streamLine/streamLineParticle.H b/src/functionObjects/field/streamLine/streamLineParticle.H index 0fc1b325e8..af6cf7ed32 100644 --- a/src/functionObjects/field/streamLine/streamLineParticle.H +++ b/src/functionObjects/field/streamLine/streamLineParticle.H @@ -86,6 +86,8 @@ public: DynamicList& allPositions_; + DynamicList& allTimes_; + List>& allScalars_; List>& allVectors_; @@ -104,6 +106,7 @@ public: const label nSubCycle, const scalar trackLength, DynamicList>& allPositions, + DynamicList>& allTimes, List>& allScalars, List>& allVectors ) @@ -116,6 +119,7 @@ public: nSubCycle_(nSubCycle), trackLength_(trackLength), allPositions_(allPositions), + allTimes_(allTimes), allScalars_(allScalars), allVectors_(allVectors) {} @@ -129,9 +133,15 @@ private: //- Lifetime of particle. Particle dies when reaches 0. label lifeTime_; + //- Age of the particle + scalar age_; + //- Sampled positions DynamicList sampledPositions_; + //- Sampled times + DynamicList sampledTimes_; + //- Sampled scalars List> sampledScalars_;