Commit 544068cf authored by Andrew Heather's avatar Andrew Heather
Browse files

ENH: First pass of introducing steady tracking

parent b3c82b63
......@@ -396,7 +396,7 @@ void Foam::Cloud<ParticleType>::cloudReset(const Cloud<ParticleType>& c)
template<class ParticleType>
template<class TrackingData>
void Foam::Cloud<ParticleType>::move(TrackingData& td)
void Foam::Cloud<ParticleType>::move(TrackingData& td, const scalar trackTime)
{
const polyBoundaryMesh& pbm = pMesh().boundaryMesh();
const globalMeshData& pData = polyMesh_.globalData();
......@@ -454,7 +454,7 @@ void Foam::Cloud<ParticleType>::move(TrackingData& td)
ParticleType& p = pIter();
// Move the particle
bool keepParticle = p.move(td);
bool keepParticle = p.move(td, trackTime);
// If the particle is to be kept
// (i.e. it hasn't passed through an inlet or outlet)
......
......@@ -324,7 +324,7 @@ public:
//- Move the particles
// passing the TrackingData to the track function
template<class TrackingData>
void move(TrackingData& td);
void move(TrackingData& td, const scalar trackTime);
//- Remap the cells of particles corresponding to the
// mesh topology change
......
......@@ -979,7 +979,10 @@ void Foam::InteractionLists<ParticleType>::fillReferredParticleCloud()
forAllConstIter(typename IDLList<ParticleType>, refCell, iter)
{
cloud_.addParticle(iter().clone().ptr());
cloud_.addParticle
(
static_cast<ParticleType*>(iter().clone().ptr())
);
}
}
}
......
......@@ -198,6 +198,25 @@ Foam::Particle<ParticleType>::Particle(const Particle<ParticleType>& p)
{}
template<class ParticleType>
Foam::Particle<ParticleType>::Particle
(
const Particle<ParticleType>& p,
const Cloud<ParticleType>& c
)
:
cloud_(c),
position_(p.position_),
cellI_(p.cellI_),
faceI_(p.faceI_),
stepFraction_(p.stepFraction_),
tetFaceI_(p.tetFaceI_),
tetPtI_(p.tetPtI_),
origProc_(p.origProc_),
origId_(p.origId_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class ParticleType>
......
......@@ -361,10 +361,28 @@ public:
//- Construct as a copy
Particle(const Particle& p);
//- Construct as a copy
Particle(const Particle& p, const Cloud<ParticleType>& c);
//- Construct a clone
autoPtr<ParticleType> clone() const
virtual autoPtr<Particle<ParticleType> > clone() const
{
return autoPtr<Particle>(new Particle(*this));
return autoPtr<Particle<ParticleType> >
(
new Particle<ParticleType>(*this)
);
}
//- Construct a clone
virtual autoPtr<Particle<ParticleType> > clone
(
const Cloud<ParticleType>& c
) const
{
return autoPtr<Particle<ParticleType> >
(
new Particle<ParticleType>(*this, c)
);
}
......
......@@ -111,6 +111,16 @@ Foam::coalParcel::coalParcel(const coalParcel& p)
}
Foam::coalParcel::coalParcel
(
const coalParcel& p,
const ReactingMultiphaseCloud<coalParcel>& c
)
:
ReactingMultiphaseParcel<coalParcel>(p, c)
{}
// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * //
Foam::coalParcel::~coalParcel()
......
......@@ -103,10 +103,33 @@ public:
//- Construct as a copy
coalParcel(const coalParcel& p);
//- Construct and return a clone
autoPtr<coalParcel> clone() const
//- Construct as a copy
coalParcel
(
const coalParcel& p,
const ReactingMultiphaseCloud<coalParcel>& c
);
//- Construct and return a (basic particle) clone
virtual autoPtr<Particle<coalParcel> > clone() const
{
return autoPtr<Particle<coalParcel> >(new coalParcel(*this));
}
//- Construct and return a (basic particle) clone
virtual autoPtr<Particle<coalParcel> > clone
(
const Cloud<coalParcel>& c
) const
{
return autoPtr<coalParcel>(new coalParcel(*this));
return autoPtr<Particle<coalParcel> >
(
new coalParcel
(
*this,
static_cast<const ReactingMultiphaseCloud<coalParcel>&>(c)
)
);
}
......
......@@ -41,8 +41,16 @@ License
template<class ParcelType>
void Foam::KinematicCloud<ParcelType>::cloudSolution::read()
{
dict_.lookup("transient") >> transient_;
dict_.lookup("coupled") >> coupled_;
dict_.lookup("cellValueSourceCorrection") >> cellValueSourceCorrection_;
if (steadyState())
{
dict_.lookup("maxTrackTime") >> maxTrackTime_;
dict_.subDict("sourceTerms").lookup("resetOnStartup")
>> resetSourcesOnStartup_;
}
}
......@@ -56,8 +64,11 @@ Foam::KinematicCloud<ParcelType>::cloudSolution::cloudSolution
mesh_(mesh),
dict_(dict),
active_(dict.lookup("active")),
transient_(false),
coupled_(false),
cellValueSourceCorrection_(false)
cellValueSourceCorrection_(false),
maxTrackTime_(0.0),
resetSourcesOnStartup_(false)
{
if (active_)
{
......@@ -75,8 +86,11 @@ Foam::KinematicCloud<ParcelType>::cloudSolution::cloudSolution
mesh_(cs.mesh_),
dict_(cs.dict_),
active_(cs.active_),
transient_(cs.transient_),
coupled_(cs.coupled_),
cellValueSourceCorrection_(cs.cellValueSourceCorrection_)
cellValueSourceCorrection_(cs.cellValueSourceCorrection_),
maxTrackTime_(cs.maxTrackTime_),
resetSourcesOnStartup_(cs.resetSourcesOnStartup_)
{}
......@@ -89,8 +103,11 @@ Foam::KinematicCloud<ParcelType>::cloudSolution::cloudSolution
mesh_(mesh),
dict_(dictionary::null),
active_(false),
transient_(false),
coupled_(false),
cellValueSourceCorrection_(false)
cellValueSourceCorrection_(false),
maxTrackTime_(0.0),
resetSourcesOnStartup_(false)
{}
......@@ -99,6 +116,30 @@ Foam::KinematicCloud<ParcelType>::cloudSolution::~cloudSolution()
{}
template<class ParcelType>
Foam::scalar Foam::KinematicCloud<ParcelType>::cloudSolution::relaxCoeff
(
const word& fieldName
) const
{
return readScalar(sourceTermDict().subDict(fieldName).lookup("alpha"));
}
template<class ParcelType>
bool Foam::KinematicCloud<ParcelType>::cloudSolution::sourceActive() const
{
return coupled_ && (active_ || steadyState());
}
template<class ParcelType>
bool Foam::KinematicCloud<ParcelType>::cloudSolution::writeThisStep() const
{
return active_ && mesh_.time().outputTime();
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class ParcelType>
......@@ -127,6 +168,8 @@ void Foam::KinematicCloud<ParcelType>::restoreState()
template<class ParcelType>
void Foam::KinematicCloud<ParcelType>::preEvolve()
{
Info<< "\nSolving cloud " << this->name() << endl;
this->dispersion().cacheFields(true);
forces_.cacheFields(true, solution_.interpolationSchemes());
updateCellOccupancy();
......@@ -184,28 +227,41 @@ void Foam::KinematicCloud<ParcelType>::evolveCloud
typename ParcelType::trackData& td
)
{
label preInjectionSize = this->size();
this->surfaceFilm().inject(td);
// Update the cellOccupancy if the size of the cloud has changed
// during the injection.
if (preInjectionSize != this->size())
if (solution_.coupled())
{
updateCellOccupancy();
preInjectionSize = this->size();
resetSourceTerms();
}
this->injection().inject(td);
if (solution_.coupled())
if (solution_.transient())
{
resetSourceTerms();
label preInjectionSize = this->size();
this->surfaceFilm().inject(td);
// Update the cellOccupancy if the size of the cloud has changed
// during the injection.
if (preInjectionSize != this->size())
{
updateCellOccupancy();
preInjectionSize = this->size();
}
this->injection().inject(td);
// Assume that motion will update the cellOccupancy as necessary
// before it is required.
motion(td);
}
else
{
// this->surfaceFilm().injectStreadyState(td);
this->injection().injectSteadyState(td, solution_.maxTrackTime());
// Assume that motion will update the cellOccupancy as necessary
// before it is required.
motion(td);
td.part() = ParcelType::trackData::tpVelocityHalfStep;
Cloud<ParcelType>::move(td, solution_.maxTrackTime());
}
}
......@@ -254,10 +310,10 @@ void Foam::KinematicCloud<ParcelType>::moveCollide
)
{
td.part() = ParcelType::trackData::tpVelocityHalfStep;
Cloud<ParcelType>::move(td);
Cloud<ParcelType>::move(td, this->db().time().deltaTValue());
td.part() = ParcelType::trackData::tpLinearTrack;
Cloud<ParcelType>::move(td);
Cloud<ParcelType>::move(td, this->db().time().deltaTValue());
// td.part() = ParcelType::trackData::tpRotationalTrack;
// Cloud<ParcelType>::move(td);
......@@ -267,13 +323,15 @@ void Foam::KinematicCloud<ParcelType>::moveCollide
this->collision().collide();
td.part() = ParcelType::trackData::tpVelocityHalfStep;
Cloud<ParcelType>::move(td);
Cloud<ParcelType>::move(td, this->db().time().deltaTValue());
}
template<class ParcelType>
void Foam::KinematicCloud<ParcelType>::postEvolve()
{
Info<< endl;
if (debug)
{
this->writePositions();
......@@ -304,6 +362,13 @@ void Foam::KinematicCloud<ParcelType>::cloudReset(KinematicCloud<ParcelType>& c)
}
template<class ParcelType>
void Foam::KinematicCloud<ParcelType>::relaxSources()
{
this->relax(UTrans_(), cloudCopyPtr_->UTrans(), "U");
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class ParcelType>
......@@ -433,6 +498,11 @@ Foam::KinematicCloud<ParcelType>::KinematicCloud
{
ParcelType::readFields(*this);
}
if (solution_.resetSourcesOnStartup())
{
resetSourceTerms();
}
}
......@@ -555,7 +625,7 @@ void Foam::KinematicCloud<ParcelType>::checkParcelProperties
parcel.rho() = constProps_.rho0();
}
scalar carrierDt = this->db().time().deltaTValue();
const scalar carrierDt = this->db().time().deltaTValue();
parcel.stepFraction() = (carrierDt - lagrangianDt)/carrierDt;
}
......@@ -563,7 +633,22 @@ void Foam::KinematicCloud<ParcelType>::checkParcelProperties
template<class ParcelType>
void Foam::KinematicCloud<ParcelType>::resetSourceTerms()
{
UTrans_->field() = vector::zero;
UTrans().field() = vector::zero;
}
template<class ParcelType>
template<class Type>
void Foam::KinematicCloud<ParcelType>::relax
(
DimensionedField<Type, volMesh>& field,
const DimensionedField<Type, volMesh>& field0,
const word& name
) const
{
const scalar coeff = solution_.relaxCoeff(name);
field = field0 + coeff*(field - field0);
}
......@@ -574,14 +659,31 @@ void Foam::KinematicCloud<ParcelType>::evolve()
{
typename ParcelType::trackData td(*this);
preEvolve();
if (solution_.transient())
{
preEvolve();
evolveCloud(td);
evolveCloud(td);
}
else
{
storeState();
postEvolve();
preEvolve();
evolveCloud(td);
relaxSources();
}
info();
Info<< endl;
postEvolve();
if (solution_.steadyState())
{
restoreState();
}
}
}
......
......@@ -27,14 +27,16 @@ Class
Description
Templated base class for kinematic cloud
- Kinematic only
- holds a 'cloudSolution' class that stores all relevant solution info
- sub-models:
- Collision model
- Dispersion model
- Drag model
- Injection model
- Patch interaction model
- Post-processing model
- Surface film model
- Collision model
SourceFiles
KinematicCloudI.H
......@@ -133,6 +135,9 @@ public:
//- Cloud active flag
const Switch active_;
//- Transient flag
Switch transient_;
// Run-time options
......@@ -145,6 +150,19 @@ public:
// during the lagrangian timestep
Switch cellValueSourceCorrection_;
//- Maximum particle track time [s]
scalar maxTrackTime_;
//- Flag to indicate whether coupling source terms should be
// reset on start-up/first read
Switch resetSourcesOnStartup_;
// Private Member Functions
//- Disallow default bitwise assignment
void operator=(const cloudSolution&);
public:
......@@ -169,8 +187,12 @@ public:
//- Read properties from dictionary
void read();
// Access
//- Return relaxation coefficient for field
scalar relaxCoeff(const word& fieldName) const;
//- Return reference to the mesh
inline const fvMesh& mesh() const;
......@@ -180,17 +202,41 @@ public:
//- Return the active flag
inline const Switch active() const;
//- Return const access to the transient flag
inline const Switch transient() const;
//- Return const access to the steady flag
inline const Switch steadyState() const;
//- Return const access to the coupled flag
inline const Switch coupled() const;
//- Return const access to the cell value correction flag
inline const Switch cellValueSourceCorrection() const;
//- Return const access to the particle track time
inline scalar maxTrackTime() const;
//- Return const access to the reset sources flag
inline const Switch resetSourcesOnStartup() const;
//- Source terms dictionary
inline const dictionary& sourceTermDict() const;
//- Interpolation schemes dictionary
inline const dictionary& interpolationSchemes() const;
//- Integration schemes dictionary
inline const dictionary& integrationSchemes() const;
// Helper functions
//- Returns true if sources are active (at this time)
bool sourceActive() const;
//- Returns true if writing this step
bool writeThisStep() const;
};
......@@ -311,6 +357,9 @@ protected:
//- Reset state of cloud
void cloudReset(KinematicCloud<ParcelType>& c);
//- Apply relaxation to (steady state) cloud sources
void relaxSources();
public:
......@@ -543,10 +592,19 @@ public:
const bool fullyDescribed
);
//- Reset the spray source terms
//- Reset the cloud source terms
void resetSourceTerms();
//- Evolve the spray (inject, inject)
//- Relax field
template<class Type>
void relax
(
DimensionedField<Type, volMesh>& field,
const DimensionedField<Type, volMesh>& field0,
const word& name
) const;
//- Evolve the cloud
void evolve();
};
......
......@@ -51,6 +51,46 @@ Foam::KinematicCloud<ParcelType>::cloudSolution::active() const
}
template<class ParcelType>
inline const Foam::dictionary&
Foam::KinematicCloud<ParcelType>::cloudSolution::sourceTermDict() const
{
return dict_.subDict("sourceTerms");
}
template<class ParcelType>
inline const Foam::dictionary&
Foam::KinematicCloud<ParcelType>::cloudSolution::interpolationSchemes() const
{
return dict_.subDict("interpolationSchemes");
}
template<class ParcelType>
inline const Foam::dictionary&
Foam::KinematicCloud<ParcelType>::cloudSolution::integrationSchemes() const
{
return dict_.subDict("integrationSchemes");
}