Merge branch 'master' of github.com-OpenFOAM:OpenFOAM/OpenFOAM-dev
This commit is contained in:
@ -1,137 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::SubDimensionedField
|
||||
|
||||
Description
|
||||
SubDimensionedField is a DimensionedField obtained as a section of another
|
||||
DimensionedField.
|
||||
|
||||
Thus it is itself unallocated so that no storage is allocated or
|
||||
deallocated during its use. To achieve this behaviour,
|
||||
SubDimensionedField is derived from SubField rather than Field.
|
||||
|
||||
SourceFiles
|
||||
SubDimensionedFieldI.H
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef SubDimensionedField_H
|
||||
#define SubDimensionedField_H
|
||||
|
||||
#include "Field.H"
|
||||
#include "SubField.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class SubDimensionedField Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class Type, class GeoMesh>
|
||||
class SubDimensionedField
|
||||
:
|
||||
public regIOobject,
|
||||
public SubField<Type>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
// Public typedefs
|
||||
|
||||
typedef typename GeoMesh::Mesh Mesh;
|
||||
typedef typename Field<Type>::cmptType cmptType;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from a SubField
|
||||
inline SubDimensionedField
|
||||
(
|
||||
const SubField<Type>& slist
|
||||
);
|
||||
|
||||
//- Construct from a UList and size
|
||||
inline SubDimensionedField
|
||||
(
|
||||
const UList<Type>& list,
|
||||
const label subSize
|
||||
);
|
||||
|
||||
//- Construct from a UList start and end indices
|
||||
inline SubDimensionedField
|
||||
(
|
||||
const UList<Type>& list,
|
||||
const label subSize,
|
||||
const label startIndex
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
inline SubDimensionedField
|
||||
(
|
||||
const SubDimensionedField<cmptType, GeoMesh>& sfield
|
||||
);
|
||||
|
||||
|
||||
// Member functions
|
||||
|
||||
//- Return a null SubDimensionedField
|
||||
static inline const SubDimensionedField<Type, GeoMesh>& null();
|
||||
|
||||
//- Return a component field of the field
|
||||
inline tmp<DimensionedField<cmptType, GeoMesh>> component
|
||||
(
|
||||
const direction
|
||||
) const;
|
||||
|
||||
//- Return the field transpose (only defined for second rank tensors)
|
||||
tmp<DimensionedField<Type, GeoMesh>> T() const;
|
||||
|
||||
|
||||
// Member operators
|
||||
|
||||
//- Assignment
|
||||
inline void operator=(const SubDimensionedField<Type, GeoMesh>&);
|
||||
|
||||
//- Allow cast to a const DimensionedField<Type, GeoMesh>&
|
||||
inline operator const DimensionedField<Type, GeoMesh>&() const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "SubDimensionedFieldI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,131 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type, class GeoMesh>
|
||||
inline Foam::SubDimensionedField<Type, GeoMesh>::SubDimensionedField
|
||||
(
|
||||
const SubField<Type>& slist
|
||||
)
|
||||
:
|
||||
SubField<Type>(slist)
|
||||
{}
|
||||
|
||||
template<class Type, class GeoMesh>
|
||||
inline Foam::SubDimensionedField<Type, GeoMesh>::SubDimensionedField
|
||||
(
|
||||
const UList<Type>& list,
|
||||
const label subSize
|
||||
)
|
||||
:
|
||||
SubField<Type>(list, subSize)
|
||||
{}
|
||||
|
||||
|
||||
template<class Type, class GeoMesh>
|
||||
inline Foam::SubDimensionedField<Type, GeoMesh>::SubDimensionedField
|
||||
(
|
||||
const UList<Type>& list,
|
||||
const label subSize,
|
||||
const label startIndex
|
||||
)
|
||||
:
|
||||
SubField<Type>(list, subSize, startIndex)
|
||||
{}
|
||||
|
||||
|
||||
template<class Type, class GeoMesh>
|
||||
inline Foam::SubDimensionedField<Type, GeoMesh>::SubDimensionedField
|
||||
(
|
||||
const SubDimensionedField<Type, GeoMesh>& sfield
|
||||
)
|
||||
:
|
||||
tmp<SubDimensionedField<Type, GeoMesh>>::refCount(),
|
||||
SubField<Type>(sfield)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type, class GeoMesh>
|
||||
inline const Foam::SubDimensionedField<Type, GeoMesh>&
|
||||
Foam::SubDimensionedField<Type, GeoMesh>::null()
|
||||
{
|
||||
return NullObjectRef<SubDimensionedField<Type, GeoMesh>>();
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class GeoMesh>
|
||||
inline
|
||||
Foam::tmp
|
||||
<
|
||||
Foam::Field<typename Foam::SubDimensionedField<Type, GeoMesh>::cmptType>
|
||||
>
|
||||
Foam::SubDimensionedField<Type, GeoMesh>::component
|
||||
(
|
||||
const direction d
|
||||
) const
|
||||
{
|
||||
return
|
||||
(
|
||||
reinterpret_cast<const DimensionedField<Type, GeoMesh>&>(*this)
|
||||
).component(d);
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class GeoMesh>
|
||||
inline Foam::tmp<Foam::DimensionedField<Type, GeoMesh>>
|
||||
Foam::SubDimensionedField<Type, GeoMesh>::T() const
|
||||
{
|
||||
return
|
||||
(
|
||||
reinterpret_cast<const DimensionedField<Type, GeoMesh>&>(*this)
|
||||
).T();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type, class GeoMesh>
|
||||
inline void Foam::SubDimensionedField<Type, GeoMesh>::operator=
|
||||
(
|
||||
const SubDimensionedField<Type, GeoMesh>& rhs
|
||||
)
|
||||
{
|
||||
dimensions() = rhs.dimensions();
|
||||
SubField<Type>::operator=(rhs);
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class GeoMesh>
|
||||
inline Foam::SubDimensionedField<Type, GeoMesh>::operator
|
||||
const Foam::DimensionedField<Type, GeoMesh>&() const
|
||||
{
|
||||
return *(reinterpret_cast<const DimensionedField<Type, GeoMesh>*>(this));
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -30,7 +30,6 @@ License
|
||||
|
||||
#include "CellZoneInjection.H"
|
||||
#include "ConeInjection.H"
|
||||
#include "ConeNozzleInjection.H"
|
||||
#include "FieldActivatedInjection.H"
|
||||
#include "InflationInjection.H"
|
||||
#include "KinematicLookupTableInjection.H"
|
||||
@ -47,7 +46,6 @@ License
|
||||
\
|
||||
makeInjectionModelType(CellZoneInjection, CloudType); \
|
||||
makeInjectionModelType(ConeInjection, CloudType); \
|
||||
makeInjectionModelType(ConeNozzleInjection, CloudType); \
|
||||
makeInjectionModelType(FieldActivatedInjection, CloudType); \
|
||||
makeInjectionModelType(InflationInjection, CloudType); \
|
||||
makeInjectionModelType(KinematicLookupTableInjection, CloudType); \
|
||||
|
||||
@ -30,7 +30,6 @@ License
|
||||
|
||||
#include "CellZoneInjection.H"
|
||||
#include "ConeInjection.H"
|
||||
#include "ConeNozzleInjection.H"
|
||||
#include "FieldActivatedInjection.H"
|
||||
#include "ManualInjection.H"
|
||||
#include "NoInjection.H"
|
||||
@ -45,7 +44,6 @@ License
|
||||
makeInjectionModel(CloudType); \
|
||||
makeInjectionModelType(CellZoneInjection, CloudType); \
|
||||
makeInjectionModelType(ConeInjection, CloudType); \
|
||||
makeInjectionModelType(ConeNozzleInjection, CloudType); \
|
||||
makeInjectionModelType(FieldActivatedInjection, CloudType); \
|
||||
makeInjectionModelType(ManualInjection, CloudType); \
|
||||
makeInjectionModelType(NoInjection, CloudType); \
|
||||
|
||||
@ -30,7 +30,6 @@ License
|
||||
|
||||
#include "CellZoneInjection.H"
|
||||
#include "ConeInjection.H"
|
||||
#include "ConeNozzleInjection.H"
|
||||
#include "FieldActivatedInjection.H"
|
||||
#include "ManualInjection.H"
|
||||
#include "NoInjection.H"
|
||||
@ -45,7 +44,6 @@ License
|
||||
makeInjectionModel(CloudType); \
|
||||
makeInjectionModelType(CellZoneInjection, CloudType); \
|
||||
makeInjectionModelType(ConeInjection, CloudType); \
|
||||
makeInjectionModelType(ConeNozzleInjection, CloudType); \
|
||||
makeInjectionModelType(FieldActivatedInjection, CloudType); \
|
||||
makeInjectionModelType(ManualInjection, CloudType); \
|
||||
makeInjectionModelType(NoInjection, CloudType); \
|
||||
|
||||
@ -30,6 +30,81 @@ License
|
||||
|
||||
using namespace Foam::constant::mathematical;
|
||||
|
||||
// * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ConeInjection<CloudType>::setInjectionMethod()
|
||||
{
|
||||
const word injectionMethod =
|
||||
this->coeffDict().template lookupOrDefault<word>
|
||||
(
|
||||
"injectionMethod",
|
||||
word::null
|
||||
);
|
||||
|
||||
if (injectionMethod == "point" || injectionMethod == word::null)
|
||||
{
|
||||
injectionMethod_ = imPoint;
|
||||
|
||||
updateMesh();
|
||||
}
|
||||
else if (injectionMethod == "disc")
|
||||
{
|
||||
injectionMethod_ = imDisc;
|
||||
|
||||
this->coeffDict().lookup("dInner") >> dInner_;
|
||||
this->coeffDict().lookup("dOuter") >> dOuter_;
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "injectionMethod must be either 'point' or 'disc'"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ConeInjection<CloudType>::setFlowType()
|
||||
{
|
||||
const word flowType =
|
||||
this->coeffDict().template lookupOrDefault<word>
|
||||
(
|
||||
"flowType",
|
||||
word::null
|
||||
);
|
||||
|
||||
if (flowType == "constantVelocity" || flowType == word::null)
|
||||
{
|
||||
flowType_ = ftConstantVelocity;
|
||||
|
||||
Umag_.reset(this->coeffDict());
|
||||
}
|
||||
else if (flowType == "pressureDrivenVelocity")
|
||||
{
|
||||
flowType_ = ftPressureDrivenVelocity;
|
||||
|
||||
Pinj_.reset(this->coeffDict());
|
||||
}
|
||||
else if (flowType == "flowRateAndDischarge")
|
||||
{
|
||||
flowType_ = ftFlowRateAndDischarge;
|
||||
|
||||
this->coeffDict().lookup("dInner") >> dInner_;
|
||||
this->coeffDict().lookup("dOuter") >> dOuter_;
|
||||
|
||||
Cd_.reset(this->coeffDict());
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "flowType must be either 'constantVelocity', "
|
||||
<< "'pressureDrivenVelocity' or 'flowRateAndDischarge'"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class CloudType>
|
||||
@ -41,14 +116,17 @@ Foam::ConeInjection<CloudType>::ConeInjection
|
||||
)
|
||||
:
|
||||
InjectionModel<CloudType>(dict, owner, modelName, typeName),
|
||||
positionAxis_(this->coeffDict().lookup("positionAxis")),
|
||||
injectorCells_(positionAxis_.size()),
|
||||
injectorTetFaces_(positionAxis_.size()),
|
||||
injectorTetPts_(positionAxis_.size()),
|
||||
injectionMethod_(imPoint),
|
||||
flowType_(ftConstantVelocity),
|
||||
position_(this->coeffDict().lookup("position")),
|
||||
direction_(this->coeffDict().lookup("direction")),
|
||||
injectorCell_(-1),
|
||||
injectorTetFace_(-1),
|
||||
injectorTetPt_(-1),
|
||||
duration_(readScalar(this->coeffDict().lookup("duration"))),
|
||||
parcelsPerInjector_
|
||||
parcelsPerSecond_
|
||||
(
|
||||
readScalar(this->coeffDict().lookup("parcelsPerInjector"))
|
||||
readScalar(this->coeffDict().lookup("parcelsPerSecond"))
|
||||
),
|
||||
flowRateProfile_
|
||||
(
|
||||
@ -59,15 +137,6 @@ Foam::ConeInjection<CloudType>::ConeInjection
|
||||
this->coeffDict()
|
||||
)
|
||||
),
|
||||
Umag_
|
||||
(
|
||||
TimeFunction1<scalar>
|
||||
(
|
||||
owner.db().time(),
|
||||
"Umag",
|
||||
this->coeffDict()
|
||||
)
|
||||
),
|
||||
thetaInner_
|
||||
(
|
||||
TimeFunction1<scalar>
|
||||
@ -93,26 +162,28 @@ Foam::ConeInjection<CloudType>::ConeInjection
|
||||
this->coeffDict().subDict("sizeDistribution"), owner.rndGen()
|
||||
)
|
||||
),
|
||||
nInjected_(this->parcelsAddedTotal()),
|
||||
tanVec1_(positionAxis_.size()),
|
||||
tanVec2_(positionAxis_.size())
|
||||
tanVec1_(vector::max),
|
||||
tanVec2_(vector::max),
|
||||
dInner_(vGreat),
|
||||
dOuter_(vGreat),
|
||||
Umag_(owner.db().time(), "Umag"),
|
||||
Cd_(owner.db().time(), "Cd"),
|
||||
Pinj_(owner.db().time(), "Pinj")
|
||||
{
|
||||
duration_ = owner.db().time().userTimeToTime(duration_);
|
||||
|
||||
setInjectionMethod();
|
||||
|
||||
setFlowType();
|
||||
|
||||
// Normalise direction vector and determine direction vectors
|
||||
// tangential to injector axis direction
|
||||
forAll(positionAxis_, i)
|
||||
{
|
||||
vector& axis = positionAxis_[i].second();
|
||||
|
||||
axis /= mag(axis);
|
||||
|
||||
tanVec1_[i] = normalised(perpendicular(axis));
|
||||
tanVec2_[i] = normalised(axis^tanVec1_[i]);
|
||||
}
|
||||
// tangential to injector direction
|
||||
direction_ /= mag(direction_);
|
||||
tanVec1_ = normalised(perpendicular(direction_));
|
||||
tanVec2_ = normalised(direction_^tanVec1_);
|
||||
|
||||
// Set total volume to inject
|
||||
this->volumeTotal_ = flowRateProfile_.integrate(0.0, duration_);
|
||||
this->volumeTotal_ = flowRateProfile_.integrate(0, duration_);
|
||||
|
||||
updateMesh();
|
||||
}
|
||||
@ -125,20 +196,26 @@ Foam::ConeInjection<CloudType>::ConeInjection
|
||||
)
|
||||
:
|
||||
InjectionModel<CloudType>(im),
|
||||
positionAxis_(im.positionAxis_),
|
||||
injectorCells_(im.injectorCells_),
|
||||
injectorTetFaces_(im.injectorTetFaces_),
|
||||
injectorTetPts_(im.injectorTetPts_),
|
||||
injectionMethod_(im.injectionMethod_),
|
||||
flowType_(im.flowType_),
|
||||
position_(im.position_),
|
||||
direction_(im.direction_),
|
||||
injectorCell_(im.injectorCell_),
|
||||
injectorTetFace_(im.injectorTetFace_),
|
||||
injectorTetPt_(im.injectorTetPt_),
|
||||
duration_(im.duration_),
|
||||
parcelsPerInjector_(im.parcelsPerInjector_),
|
||||
parcelsPerSecond_(im.parcelsPerSecond_),
|
||||
flowRateProfile_(im.flowRateProfile_),
|
||||
Umag_(im.Umag_),
|
||||
thetaInner_(im.thetaInner_),
|
||||
thetaOuter_(im.thetaOuter_),
|
||||
sizeDistribution_(im.sizeDistribution_().clone().ptr()),
|
||||
nInjected_(im.nInjected_),
|
||||
tanVec1_(im.tanVec1_),
|
||||
tanVec2_(im.tanVec2_)
|
||||
tanVec2_(im.tanVec2_),
|
||||
dInner_(im.dInner_),
|
||||
dOuter_(im.dOuter_),
|
||||
Umag_(im.Umag_),
|
||||
Cd_(im.Cd_),
|
||||
Pinj_(im.Pinj_)
|
||||
{}
|
||||
|
||||
|
||||
@ -155,15 +232,23 @@ template<class CloudType>
|
||||
void Foam::ConeInjection<CloudType>::updateMesh()
|
||||
{
|
||||
// Set/cache the injector cells
|
||||
forAll(positionAxis_, i)
|
||||
switch (injectionMethod_)
|
||||
{
|
||||
this->findCellAtPosition
|
||||
(
|
||||
injectorCells_[i],
|
||||
injectorTetFaces_[i],
|
||||
injectorTetPts_[i],
|
||||
positionAxis_[i].first()
|
||||
);
|
||||
case imPoint:
|
||||
{
|
||||
this->findCellAtPosition
|
||||
(
|
||||
injectorCell_,
|
||||
injectorTetFace_,
|
||||
injectorTetPt_,
|
||||
position_
|
||||
);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,18 +267,13 @@ Foam::label Foam::ConeInjection<CloudType>::parcelsToInject
|
||||
const scalar time1
|
||||
)
|
||||
{
|
||||
if ((time0 >= 0.0) && (time0 < duration_))
|
||||
if (time0 >= 0 && time0 < duration_)
|
||||
{
|
||||
const scalar targetVolume = flowRateProfile_.integrate(0, time1);
|
||||
//// Standard calculation
|
||||
//return floor(parcelsPerSecond_*(time1 - time0));
|
||||
|
||||
const label targetParcels =
|
||||
parcelsPerInjector_*targetVolume/this->volumeTotal_;
|
||||
|
||||
const label nToInject = targetParcels - nInjected_;
|
||||
|
||||
nInjected_ += nToInject;
|
||||
|
||||
return positionAxis_.size()*nToInject;
|
||||
// Modified calculation to make numbers exact
|
||||
return floor(parcelsPerSecond_*time1 - this->parcelsAddedTotal());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -209,13 +289,13 @@ Foam::scalar Foam::ConeInjection<CloudType>::volumeToInject
|
||||
const scalar time1
|
||||
)
|
||||
{
|
||||
if ((time0 >= 0.0) && (time0 < duration_))
|
||||
if (time0 >= 0 && time0 < duration_)
|
||||
{
|
||||
return flowRateProfile_.integrate(time0, time1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0.0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -232,12 +312,40 @@ void Foam::ConeInjection<CloudType>::setPositionAndCell
|
||||
label& tetPti
|
||||
)
|
||||
{
|
||||
const label i = parcelI % positionAxis_.size();
|
||||
Random& rndGen = this->owner().rndGen();
|
||||
|
||||
position = positionAxis_[i].first();
|
||||
cellOwner = injectorCells_[i];
|
||||
tetFacei = injectorTetFaces_[i];
|
||||
tetPti = injectorTetPts_[i];
|
||||
switch (injectionMethod_)
|
||||
{
|
||||
case imPoint:
|
||||
{
|
||||
position = position_;
|
||||
cellOwner = injectorCell_;
|
||||
tetFacei = injectorTetFace_;
|
||||
tetPti = injectorTetPt_;
|
||||
break;
|
||||
}
|
||||
case imDisc:
|
||||
{
|
||||
const scalar beta = twoPi*rndGen.globalScalar01();
|
||||
const scalar frac = rndGen.globalScalar01();
|
||||
const vector tanVec = tanVec1_*cos(beta) + tanVec2_*sin(beta);
|
||||
const scalar d = sqrt((1 - frac)*sqr(dInner_) + frac*sqr(dOuter_));
|
||||
position = position_ + d/2*tanVec;
|
||||
this->findCellAtPosition
|
||||
(
|
||||
cellOwner,
|
||||
tetFacei,
|
||||
tetPti,
|
||||
position,
|
||||
false
|
||||
);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -250,29 +358,92 @@ void Foam::ConeInjection<CloudType>::setProperties
|
||||
typename CloudType::parcelType& parcel
|
||||
)
|
||||
{
|
||||
Random& rnd = this->owner().rndGen();
|
||||
Random& rndGen = this->owner().rndGen();
|
||||
|
||||
// set particle velocity
|
||||
const label i = parcelI % positionAxis_.size();
|
||||
const scalar t = time - this->SOI_;
|
||||
|
||||
scalar t = time - this->SOI_;
|
||||
scalar ti = thetaInner_.value(t);
|
||||
scalar to = thetaOuter_.value(t);
|
||||
scalar coneAngle = degToRad(rnd.scalarAB(ti, to));
|
||||
// Get the angle from the axis and the vector perpendicular from the axis.
|
||||
// If injecting at a point, then these are calculated from two new random
|
||||
// numbers. If a disc, then these calculations have already been done in
|
||||
// setPositionAndCell, so the angle and vector can be reverse engineered
|
||||
// from the position.
|
||||
scalar theta = vGreat;
|
||||
vector tanVec = vector::max;
|
||||
switch (injectionMethod_)
|
||||
{
|
||||
case imPoint:
|
||||
{
|
||||
const scalar beta = twoPi*rndGen.scalar01();
|
||||
const scalar frac = rndGen.scalar01();
|
||||
tanVec = tanVec1_*cos(beta) + tanVec2_*sin(beta);
|
||||
theta =
|
||||
degToRad
|
||||
(
|
||||
sqrt
|
||||
(
|
||||
(1 - frac)*sqr(thetaInner_.value(t))
|
||||
+ frac*sqr(thetaOuter_.value(t))
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
case imDisc:
|
||||
{
|
||||
const scalar r = mag(parcel.position() - position_);
|
||||
const scalar frac = (2*r - dInner_)/(dOuter_ - dInner_);
|
||||
tanVec = normalised(parcel.position() - position_);
|
||||
theta =
|
||||
degToRad
|
||||
(
|
||||
(1 - frac)*thetaInner_.value(t)
|
||||
+ frac*thetaOuter_.value(t)
|
||||
);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
scalar alpha = sin(coneAngle);
|
||||
scalar dcorr = cos(coneAngle);
|
||||
scalar beta = twoPi*rnd.sample01<scalar>();
|
||||
// The direction of injection
|
||||
const vector dirVec =
|
||||
normalised(cos(theta)*direction_ + sin(theta)*tanVec);
|
||||
|
||||
vector normal = alpha*(tanVec1_[i]*cos(beta) + tanVec2_[i]*sin(beta));
|
||||
vector dirVec = dcorr*positionAxis_[i].second();
|
||||
dirVec += normal;
|
||||
dirVec /= mag(dirVec);
|
||||
// Set the velocity
|
||||
switch (flowType_)
|
||||
{
|
||||
case ftConstantVelocity:
|
||||
{
|
||||
parcel.U() = Umag_.value(t)*dirVec;
|
||||
break;
|
||||
}
|
||||
case ftPressureDrivenVelocity:
|
||||
{
|
||||
const scalar pAmbient = this->owner().pAmbient();
|
||||
const scalar rho = parcel.rho();
|
||||
const scalar Umag = ::sqrt(2*(Pinj_.value(t) - pAmbient)/rho);
|
||||
parcel.U() = Umag*dirVec;
|
||||
break;
|
||||
}
|
||||
case ftFlowRateAndDischarge:
|
||||
{
|
||||
const scalar A = 0.25*pi*(sqr(dOuter_) - sqr(dInner_));
|
||||
const scalar massFlowRate =
|
||||
this->massTotal()*flowRateProfile_.value(t)/this->volumeTotal();
|
||||
const scalar Umag =
|
||||
massFlowRate/(parcel.rho()*Cd_.value(t)*A);
|
||||
parcel.U() = Umag*dirVec;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
parcel.U() = Umag_.value(t)*dirVec;
|
||||
|
||||
// set particle diameter
|
||||
parcel.d() = sizeDistribution_().sample();
|
||||
// Set the particle diameter
|
||||
parcel.d() = sizeDistribution_->sample();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -25,17 +25,112 @@ Class
|
||||
Foam::ConeInjection
|
||||
|
||||
Description
|
||||
Multi-point cone injection model.
|
||||
This injector injects particles in a number of cones. The user specifies a
|
||||
position and a direction to inject at, and two angles to inject between.
|
||||
Optionally, this injector can introduce particles over a disc, instead of
|
||||
at a point, in which case inner and outer diameters of the disc are also
|
||||
specified.
|
||||
|
||||
User specifies:
|
||||
- time of start of injection
|
||||
- list of injector positions and directions (along injection axes)
|
||||
- number of parcels to inject per injector
|
||||
- parcel velocities
|
||||
- inner and outer half-cone angles
|
||||
The velocity is specified either as constant, or it is calculated from an
|
||||
injection pressure, or it is calculated from the injector mass flow rate
|
||||
and a discharge coefficient; i.e.:
|
||||
|
||||
Properties:
|
||||
- Parcel diameters obtained by distribution model
|
||||
Constant velocity:
|
||||
\f[
|
||||
U = U_{constant}
|
||||
\f]
|
||||
|
||||
Pressure driven velocity:
|
||||
\f[
|
||||
U = \sqrt{2(p_{injection} - p)/\rho}
|
||||
\f]
|
||||
|
||||
Flow rate and discharge:
|
||||
\f[
|
||||
U = \dot{m}/(\rho A C_{discharge})
|
||||
\f]
|
||||
|
||||
Usage
|
||||
\table
|
||||
Property | Description | Required | Default
|
||||
position | The injection position | yes |
|
||||
direction | The injection direction | yes |
|
||||
thetaInner | The inner cone angle | yes |
|
||||
thetaOuter | The outer cone angle | yes |
|
||||
injectionMethod | Inject at a point or on a disc | no | point
|
||||
dInner | The inner disc diameter |\\
|
||||
if disc or flowRateAndDischarge |
|
||||
dInner | The outer disc diameter |\\
|
||||
if disc or flowRateAndDischarge |
|
||||
flowType | Inject with constantVelocity, pressureDrivenVelocity \\
|
||||
or flowRateAndDischarge | no | constantVelocity
|
||||
Umag | The injection velocity | if constantVelocity |
|
||||
Pinj | The injection pressure |\\
|
||||
if pressureDrivenVelocity |
|
||||
Cd | The discharge coefficient | if flowRateAndDischarge |
|
||||
\endtable
|
||||
|
||||
Example specification:
|
||||
|
||||
\verbatim
|
||||
injectionModels
|
||||
{
|
||||
model1
|
||||
{
|
||||
type coneInjection;
|
||||
|
||||
// Times
|
||||
SOI 0;
|
||||
duration 1;
|
||||
|
||||
// Quantities
|
||||
massTotal 0; // <-- not used with these settings
|
||||
parcelBasisType fixed;
|
||||
parcelsPerSecond 1000000;
|
||||
flowRateProfile constant 1;
|
||||
nParticle 1;
|
||||
|
||||
// Sizes
|
||||
sizeDistribution
|
||||
{
|
||||
type fixedValue;
|
||||
fixedValueDistribution
|
||||
{
|
||||
value 0.0025;
|
||||
}
|
||||
}
|
||||
|
||||
// Geometry
|
||||
position (-0.15 -0.1 0);
|
||||
direction (1 0 0);
|
||||
thetaInner 0;
|
||||
thetaOuter 45;
|
||||
|
||||
// - Inject at a point
|
||||
injectionMethod point;
|
||||
|
||||
//// - Or, inject over a disc:
|
||||
//injectionMethod disc;
|
||||
//dInner 0;
|
||||
//dOuter 0.05;
|
||||
|
||||
// Velocity
|
||||
|
||||
// - Inject with constant velocity
|
||||
flowType constantVelocity;
|
||||
Umag 1;
|
||||
|
||||
//// - Or, inject with flow rate and discharge coefficient
|
||||
//// This also requires massTotal, dInner and dOuter
|
||||
//flowType flowRateAndDischarge;
|
||||
//Cd 0.9;
|
||||
|
||||
//// - Or, inject at a pressure
|
||||
//flowType pressureDrivenVelocity;
|
||||
//Pinj 10e5;
|
||||
}
|
||||
}
|
||||
\endverbatim
|
||||
|
||||
SourceFiles
|
||||
ConeInjection.C
|
||||
@ -47,7 +142,6 @@ SourceFiles
|
||||
|
||||
#include "InjectionModel.H"
|
||||
#include "distributionModel.H"
|
||||
#include "vectorList.H"
|
||||
#include "TimeFunction1.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -64,32 +158,58 @@ class ConeInjection
|
||||
:
|
||||
public InjectionModel<CloudType>
|
||||
{
|
||||
public:
|
||||
|
||||
//- Injection method enumeration
|
||||
enum injectionMethod
|
||||
{
|
||||
imPoint,
|
||||
imDisc
|
||||
};
|
||||
|
||||
//- Flow type enumeration
|
||||
enum flowType
|
||||
{
|
||||
ftConstantVelocity,
|
||||
ftPressureDrivenVelocity,
|
||||
ftFlowRateAndDischarge
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private data
|
||||
|
||||
//- List of position and axis for each injector
|
||||
List<Tuple2<vector, vector>> positionAxis_;
|
||||
//- Point/disc injection method
|
||||
injectionMethod injectionMethod_;
|
||||
|
||||
//- List of cell labels corresponding to injector positions
|
||||
labelList injectorCells_;
|
||||
//- Flow type
|
||||
flowType flowType_;
|
||||
|
||||
//- List of tetFace labels corresponding to injector positions
|
||||
labelList injectorTetFaces_;
|
||||
//- Position of the injector
|
||||
vector position_;
|
||||
|
||||
//- List of tetPt labels corresponding to injector positions
|
||||
labelList injectorTetPts_;
|
||||
//- Centreline direction in which to inject
|
||||
vector direction_;
|
||||
|
||||
//- Cell label corresponding to the injector position
|
||||
label injectorCell_;
|
||||
|
||||
//- Tet-face label corresponding to the injector position
|
||||
label injectorTetFace_;
|
||||
|
||||
//- Tet-point label corresponding to the injector position
|
||||
label injectorTetPt_;
|
||||
|
||||
//- Injection duration [s]
|
||||
scalar duration_;
|
||||
|
||||
//- Number of parcels to introduce per injector
|
||||
const label parcelsPerInjector_;
|
||||
//- Number of parcels to introduce per second
|
||||
const label parcelsPerSecond_;
|
||||
|
||||
//- Flow rate profile relative to SOI []
|
||||
const TimeFunction1<scalar> flowRateProfile_;
|
||||
|
||||
//- Parcel velocity magnitude relative to SOI [m/s]
|
||||
const TimeFunction1<scalar> Umag_;
|
||||
|
||||
//- Inner half-cone angle relative to SOI [deg]
|
||||
const TimeFunction1<scalar> thetaInner_;
|
||||
|
||||
@ -99,17 +219,44 @@ class ConeInjection
|
||||
//- Parcel size distribution model
|
||||
const autoPtr<distributionModel> sizeDistribution_;
|
||||
|
||||
//- Number of parcels per injector already injected
|
||||
mutable label nInjected_;
|
||||
|
||||
|
||||
// Tangential vectors to the direction vector
|
||||
|
||||
//- First tangential vector
|
||||
vectorList tanVec1_;
|
||||
vector tanVec1_;
|
||||
|
||||
//- Second tangential vector
|
||||
vectorList tanVec2_;
|
||||
vector tanVec2_;
|
||||
|
||||
|
||||
// Disc geometry
|
||||
|
||||
//- The inner disc diameter [m]
|
||||
scalar dInner_;
|
||||
|
||||
//- The outer disc diameter [m]
|
||||
scalar dOuter_;
|
||||
|
||||
|
||||
// Velocity model coefficients
|
||||
|
||||
//- Parcel velocity [m/s]
|
||||
TimeFunction1<scalar> Umag_;
|
||||
|
||||
//- Discharge coefficient []
|
||||
TimeFunction1<scalar> Cd_;
|
||||
|
||||
//- Injection pressure [Pa]
|
||||
TimeFunction1<scalar> Pinj_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Set the injection type
|
||||
void setInjectionMethod();
|
||||
|
||||
//- Set the injection flow type
|
||||
void setFlowType();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
@ -1,430 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "ConeNozzleInjection.H"
|
||||
#include "TimeFunction1.H"
|
||||
#include "mathematicalConstants.H"
|
||||
#include "distributionModel.H"
|
||||
|
||||
using namespace Foam::constant;
|
||||
|
||||
// * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ConeNozzleInjection<CloudType>::setInjectionMethod()
|
||||
{
|
||||
word injectionMethodType = this->coeffDict().lookup("injectionMethod");
|
||||
if (injectionMethodType == "disc")
|
||||
{
|
||||
injectionMethod_ = imDisc;
|
||||
}
|
||||
else if (injectionMethodType == "point")
|
||||
{
|
||||
injectionMethod_ = imPoint;
|
||||
|
||||
// Set/cache the injector cell
|
||||
this->findCellAtPosition
|
||||
(
|
||||
injectorCell_,
|
||||
tetFacei_,
|
||||
tetPti_,
|
||||
position_,
|
||||
false
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "injectionMethod must be either 'point' or 'disc'"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ConeNozzleInjection<CloudType>::setFlowType()
|
||||
{
|
||||
word flowType = this->coeffDict().lookup("flowType");
|
||||
if (flowType == "constantVelocity")
|
||||
{
|
||||
this->coeffDict().lookup("UMag") >> UMag_;
|
||||
flowType_ = ftConstantVelocity;
|
||||
}
|
||||
else if (flowType == "pressureDrivenVelocity")
|
||||
{
|
||||
Pinj_.reset(this->coeffDict());
|
||||
flowType_ = ftPressureDrivenVelocity;
|
||||
}
|
||||
else if (flowType == "flowRateAndDischarge")
|
||||
{
|
||||
Cd_.reset(this->coeffDict());
|
||||
flowType_ = ftFlowRateAndDischarge;
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "flowType must be either 'constantVelocity', "
|
||||
<<"'pressureDrivenVelocity' or 'flowRateAndDischarge'"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class CloudType>
|
||||
Foam::ConeNozzleInjection<CloudType>::ConeNozzleInjection
|
||||
(
|
||||
const dictionary& dict,
|
||||
CloudType& owner,
|
||||
const word& modelName
|
||||
)
|
||||
:
|
||||
InjectionModel<CloudType>(dict, owner, modelName, typeName),
|
||||
injectionMethod_(imPoint),
|
||||
flowType_(ftConstantVelocity),
|
||||
outerDiameter_(readScalar(this->coeffDict().lookup("outerDiameter"))),
|
||||
innerDiameter_(readScalar(this->coeffDict().lookup("innerDiameter"))),
|
||||
duration_(readScalar(this->coeffDict().lookup("duration"))),
|
||||
position_(this->coeffDict().lookup("position")),
|
||||
injectorCell_(-1),
|
||||
tetFacei_(-1),
|
||||
tetPti_(-1),
|
||||
direction_(this->coeffDict().lookup("direction")),
|
||||
parcelsPerSecond_
|
||||
(
|
||||
readScalar(this->coeffDict().lookup("parcelsPerSecond"))
|
||||
),
|
||||
flowRateProfile_
|
||||
(
|
||||
TimeFunction1<scalar>
|
||||
(
|
||||
owner.db().time(),
|
||||
"flowRateProfile",
|
||||
this->coeffDict()
|
||||
)
|
||||
),
|
||||
thetaInner_
|
||||
(
|
||||
TimeFunction1<scalar>
|
||||
(
|
||||
owner.db().time(),
|
||||
"thetaInner",
|
||||
this->coeffDict()
|
||||
)
|
||||
),
|
||||
thetaOuter_
|
||||
(
|
||||
TimeFunction1<scalar>
|
||||
(
|
||||
owner.db().time(),
|
||||
"thetaOuter",
|
||||
this->coeffDict()
|
||||
)
|
||||
),
|
||||
sizeDistribution_
|
||||
(
|
||||
distributionModel::New
|
||||
(
|
||||
this->coeffDict().subDict("sizeDistribution"),
|
||||
owner.rndGen()
|
||||
)
|
||||
),
|
||||
tanVec1_(Zero),
|
||||
tanVec2_(Zero),
|
||||
normal_(Zero),
|
||||
|
||||
UMag_(0.0),
|
||||
Cd_(owner.db().time(), "Cd"),
|
||||
Pinj_(owner.db().time(), "Pinj")
|
||||
{
|
||||
if (innerDiameter_ >= outerDiameter_)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "innerNozzleDiameter >= outerNozzleDiameter" << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
duration_ = owner.db().time().userTimeToTime(duration_);
|
||||
|
||||
setInjectionMethod();
|
||||
|
||||
setFlowType();
|
||||
|
||||
// Normalise direction vector
|
||||
direction_ /= mag(direction_);
|
||||
|
||||
// Determine direction vectors tangential to direction
|
||||
tanVec1_ = normalised(perpendicular(direction_));
|
||||
tanVec2_ = normalised(direction_ ^ tanVec1_);
|
||||
|
||||
// Set total volume to inject
|
||||
this->volumeTotal_ = flowRateProfile_.integrate(0.0, duration_);
|
||||
|
||||
updateMesh();
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
Foam::ConeNozzleInjection<CloudType>::ConeNozzleInjection
|
||||
(
|
||||
const ConeNozzleInjection<CloudType>& im
|
||||
)
|
||||
:
|
||||
InjectionModel<CloudType>(im),
|
||||
injectionMethod_(im.injectionMethod_),
|
||||
flowType_(im.flowType_),
|
||||
outerDiameter_(im.outerDiameter_),
|
||||
innerDiameter_(im.innerDiameter_),
|
||||
duration_(im.duration_),
|
||||
position_(im.position_),
|
||||
injectorCell_(im.injectorCell_),
|
||||
tetFacei_(im.tetFacei_),
|
||||
tetPti_(im.tetPti_),
|
||||
direction_(im.direction_),
|
||||
parcelsPerSecond_(im.parcelsPerSecond_),
|
||||
flowRateProfile_(im.flowRateProfile_),
|
||||
thetaInner_(im.thetaInner_),
|
||||
thetaOuter_(im.thetaOuter_),
|
||||
sizeDistribution_(im.sizeDistribution_().clone().ptr()),
|
||||
tanVec1_(im.tanVec1_),
|
||||
tanVec2_(im.tanVec2_),
|
||||
normal_(im.normal_),
|
||||
UMag_(im.UMag_),
|
||||
Cd_(im.Cd_),
|
||||
Pinj_(im.Pinj_)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class CloudType>
|
||||
Foam::ConeNozzleInjection<CloudType>::~ConeNozzleInjection()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ConeNozzleInjection<CloudType>::updateMesh()
|
||||
{
|
||||
// Set/cache the injector cells
|
||||
switch (injectionMethod_)
|
||||
{
|
||||
case imPoint:
|
||||
{
|
||||
this->findCellAtPosition
|
||||
(
|
||||
injectorCell_,
|
||||
tetFacei_,
|
||||
tetPti_,
|
||||
position_
|
||||
);
|
||||
}
|
||||
default:
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
Foam::scalar Foam::ConeNozzleInjection<CloudType>::timeEnd() const
|
||||
{
|
||||
return this->SOI_ + duration_;
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
Foam::label Foam::ConeNozzleInjection<CloudType>::parcelsToInject
|
||||
(
|
||||
const scalar time0,
|
||||
const scalar time1
|
||||
)
|
||||
{
|
||||
if ((time0 >= 0.0) && (time0 < duration_))
|
||||
{
|
||||
return floor((time1 - time0)*parcelsPerSecond_);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
Foam::scalar Foam::ConeNozzleInjection<CloudType>::volumeToInject
|
||||
(
|
||||
const scalar time0,
|
||||
const scalar time1
|
||||
)
|
||||
{
|
||||
if ((time0 >= 0.0) && (time0 < duration_))
|
||||
{
|
||||
return flowRateProfile_.integrate(time0, time1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ConeNozzleInjection<CloudType>::setPositionAndCell
|
||||
(
|
||||
const label,
|
||||
const label,
|
||||
const scalar,
|
||||
vector& position,
|
||||
label& cellOwner,
|
||||
label& tetFacei,
|
||||
label& tetPti
|
||||
)
|
||||
{
|
||||
Random& rndGen = this->owner().rndGen();
|
||||
|
||||
scalar beta = mathematical::twoPi*rndGen.globalScalar01();
|
||||
normal_ = tanVec1_*cos(beta) + tanVec2_*sin(beta);
|
||||
|
||||
switch (injectionMethod_)
|
||||
{
|
||||
case imPoint:
|
||||
{
|
||||
position = position_;
|
||||
cellOwner = injectorCell_;
|
||||
tetFacei = tetFacei_;
|
||||
tetPti = tetPti_;
|
||||
|
||||
break;
|
||||
}
|
||||
case imDisc:
|
||||
{
|
||||
scalar frac = rndGen.globalScalar01();
|
||||
scalar dr = outerDiameter_ - innerDiameter_;
|
||||
scalar r = 0.5*(innerDiameter_ + frac*dr);
|
||||
position = position_ + r*normal_;
|
||||
|
||||
this->findCellAtPosition
|
||||
(
|
||||
cellOwner,
|
||||
tetFacei,
|
||||
tetPti,
|
||||
position,
|
||||
false
|
||||
);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Unknown injectionMethod type" << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ConeNozzleInjection<CloudType>::setProperties
|
||||
(
|
||||
const label parcelI,
|
||||
const label,
|
||||
const scalar time,
|
||||
typename CloudType::parcelType& parcel
|
||||
)
|
||||
{
|
||||
Random& rndGen = this->owner().rndGen();
|
||||
|
||||
// set particle velocity
|
||||
const scalar deg2Rad = mathematical::pi/180.0;
|
||||
|
||||
scalar t = time - this->SOI_;
|
||||
scalar ti = thetaInner_.value(t);
|
||||
scalar to = thetaOuter_.value(t);
|
||||
scalar coneAngle = rndGen.sample01<scalar>()*(to - ti) + ti;
|
||||
|
||||
coneAngle *= deg2Rad;
|
||||
scalar alpha = sin(coneAngle);
|
||||
scalar dcorr = cos(coneAngle);
|
||||
|
||||
vector normal = alpha*normal_;
|
||||
vector dirVec = dcorr*direction_;
|
||||
dirVec += normal;
|
||||
dirVec /= mag(dirVec);
|
||||
|
||||
switch (flowType_)
|
||||
{
|
||||
case ftConstantVelocity:
|
||||
{
|
||||
parcel.U() = UMag_*dirVec;
|
||||
break;
|
||||
}
|
||||
case ftPressureDrivenVelocity:
|
||||
{
|
||||
scalar pAmbient = this->owner().pAmbient();
|
||||
scalar rho = parcel.rho();
|
||||
scalar UMag = ::sqrt(2.0*(Pinj_.value(t) - pAmbient)/rho);
|
||||
parcel.U() = UMag*dirVec;
|
||||
break;
|
||||
}
|
||||
case ftFlowRateAndDischarge:
|
||||
{
|
||||
scalar Ao = 0.25*mathematical::pi*outerDiameter_*outerDiameter_;
|
||||
scalar Ai = 0.25*mathematical::pi*innerDiameter_*innerDiameter_;
|
||||
scalar massFlowRate =
|
||||
this->massTotal()
|
||||
*flowRateProfile_.value(t)
|
||||
/this->volumeTotal();
|
||||
|
||||
scalar Umag = massFlowRate/(parcel.rho()*Cd_.value(t)*(Ao - Ai));
|
||||
parcel.U() = Umag*dirVec;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// set particle diameter
|
||||
parcel.d() = sizeDistribution_->sample();
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
bool Foam::ConeNozzleInjection<CloudType>::fullyDescribed() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
bool Foam::ConeNozzleInjection<CloudType>::validInjection(const label)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,282 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::ConeNozzleInjection
|
||||
|
||||
Description
|
||||
Cone injection.
|
||||
|
||||
User specifies:
|
||||
- time of start of injection
|
||||
- injector position
|
||||
- direction (along injection axis)
|
||||
- parcel flow rate
|
||||
- inner and outer half-cone angles
|
||||
|
||||
Properties:
|
||||
- Parcel diameters obtained by size distribution model.
|
||||
|
||||
- Parcel velocity is calculated as:
|
||||
- Constant velocity:
|
||||
\verbatim
|
||||
U = \<specified by user\>
|
||||
\endverbatim
|
||||
|
||||
- Pressure driven velocity:
|
||||
\verbatim
|
||||
U = sqrt(2*(Pinj - Pamb)/rho)
|
||||
\endverbatim
|
||||
|
||||
- Flow rate and discharge:
|
||||
\verbatim
|
||||
U = V_dot/(A*Cd)
|
||||
\endverbatim
|
||||
|
||||
SourceFiles
|
||||
ConeNozzleInjection.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef ConeNozzleInjection_H
|
||||
#define ConeNozzleInjection_H
|
||||
|
||||
#include "InjectionModel.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward declaration of classes
|
||||
|
||||
template<class Type>
|
||||
class TimeFunction1;
|
||||
|
||||
class distributionModel;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class ConeNozzleInjection Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class CloudType>
|
||||
class ConeNozzleInjection
|
||||
:
|
||||
public InjectionModel<CloudType>
|
||||
{
|
||||
public:
|
||||
|
||||
//- Injection method enumeration
|
||||
enum injectionMethod
|
||||
{
|
||||
imPoint,
|
||||
imDisc
|
||||
};
|
||||
|
||||
//- Flow type enumeration
|
||||
enum flowType
|
||||
{
|
||||
ftConstantVelocity,
|
||||
ftPressureDrivenVelocity,
|
||||
ftFlowRateAndDischarge
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private data
|
||||
|
||||
//- Point/disc injection method
|
||||
injectionMethod injectionMethod_;
|
||||
|
||||
//- Flow type
|
||||
flowType flowType_;
|
||||
|
||||
//- Outer nozzle diameter [m]
|
||||
const scalar outerDiameter_;
|
||||
|
||||
//- Inner nozzle diameter [m]
|
||||
const scalar innerDiameter_;
|
||||
|
||||
//- Injection duration [s]
|
||||
scalar duration_;
|
||||
|
||||
//- Injector position [m]
|
||||
vector position_;
|
||||
|
||||
//- Cell containing injector position []
|
||||
label injectorCell_;
|
||||
|
||||
//- Index of tet face for injector cell
|
||||
label tetFacei_;
|
||||
|
||||
//- Index of tet point for injector cell
|
||||
label tetPti_;
|
||||
|
||||
//- Injector direction []
|
||||
vector direction_;
|
||||
|
||||
//- Number of parcels to introduce per second []
|
||||
const label parcelsPerSecond_;
|
||||
|
||||
//- Flow rate profile relative to SOI []
|
||||
const TimeFunction1<scalar> flowRateProfile_;
|
||||
|
||||
//- Inner half-cone angle relative to SOI [deg]
|
||||
const TimeFunction1<scalar> thetaInner_;
|
||||
|
||||
//- Outer half-cone angle relative to SOI [deg]
|
||||
const TimeFunction1<scalar> thetaOuter_;
|
||||
|
||||
//- Parcel size PDF model
|
||||
const autoPtr<distributionModel> sizeDistribution_;
|
||||
|
||||
|
||||
// Tangential vectors to the direction vector
|
||||
|
||||
//- First tangential vector
|
||||
vector tanVec1_;
|
||||
|
||||
//- Second tangential vector
|
||||
vector tanVec2_;
|
||||
|
||||
//- Injection vector orthogonal to direction
|
||||
vector normal_;
|
||||
|
||||
|
||||
// Velocity model coefficients
|
||||
|
||||
//- Constant velocity [m/s]
|
||||
scalar UMag_;
|
||||
|
||||
//- Discharge coefficient, relative to SOI [m/s]
|
||||
TimeFunction1<scalar> Cd_;
|
||||
|
||||
//- Injection pressure [Pa]
|
||||
TimeFunction1<scalar> Pinj_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Set the injection type
|
||||
void setInjectionMethod();
|
||||
|
||||
//- Set the injection flow type
|
||||
void setFlowType();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("coneNozzleInjection");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from dictionary
|
||||
ConeNozzleInjection
|
||||
(
|
||||
const dictionary& dict,
|
||||
CloudType& owner,
|
||||
const word& modelName
|
||||
);
|
||||
|
||||
//- Construct copy
|
||||
ConeNozzleInjection(const ConeNozzleInjection<CloudType>& im);
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual autoPtr<InjectionModel<CloudType>> clone() const
|
||||
{
|
||||
return autoPtr<InjectionModel<CloudType>>
|
||||
(
|
||||
new ConeNozzleInjection<CloudType>(*this)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~ConeNozzleInjection();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Set injector locations when mesh is updated
|
||||
virtual void updateMesh();
|
||||
|
||||
//- Return the end-of-injection time
|
||||
scalar timeEnd() const;
|
||||
|
||||
//- Number of parcels to introduce relative to SOI
|
||||
virtual label parcelsToInject(const scalar time0, const scalar time1);
|
||||
|
||||
//- Volume of parcels to introduce relative to SOI
|
||||
virtual scalar volumeToInject(const scalar time0, const scalar time1);
|
||||
|
||||
|
||||
// Injection geometry
|
||||
|
||||
//- Set the injection position and owner cell
|
||||
virtual void setPositionAndCell
|
||||
(
|
||||
const label parcelI,
|
||||
const label nParcels,
|
||||
const scalar time,
|
||||
vector& position,
|
||||
label& cellOwner,
|
||||
label& tetFacei,
|
||||
label& tetPti
|
||||
);
|
||||
|
||||
//- Set the parcel properties
|
||||
virtual void setProperties
|
||||
(
|
||||
const label parcelI,
|
||||
const label nParcels,
|
||||
const scalar time,
|
||||
typename CloudType::parcelType& parcel
|
||||
);
|
||||
|
||||
//- Flag to identify whether model fully describes the parcel
|
||||
virtual bool fullyDescribed() const;
|
||||
|
||||
//- Return flag to identify whether or not injection of parcelI is
|
||||
// permitted
|
||||
virtual bool validInjection(const label parcelI);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "ConeNozzleInjection.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -30,7 +30,6 @@ License
|
||||
|
||||
#include "CellZoneInjection.H"
|
||||
#include "ConeInjection.H"
|
||||
#include "ConeNozzleInjection.H"
|
||||
#include "FieldActivatedInjection.H"
|
||||
#include "InflationInjection.H"
|
||||
#include "ManualInjection.H"
|
||||
@ -46,7 +45,6 @@ License
|
||||
\
|
||||
makeInjectionModelType(CellZoneInjection, CloudType); \
|
||||
makeInjectionModelType(ConeInjection, CloudType); \
|
||||
makeInjectionModelType(ConeNozzleInjection, CloudType); \
|
||||
makeInjectionModelType(FieldActivatedInjection, CloudType); \
|
||||
makeInjectionModelType(InflationInjection, CloudType); \
|
||||
makeInjectionModelType(ManualInjection, CloudType); \
|
||||
|
||||
@ -77,15 +77,11 @@ subModels
|
||||
type coneInjection;
|
||||
SOI 0.000;
|
||||
duration 20.000;
|
||||
positionAxis
|
||||
(
|
||||
((0.3 0.35 1.45) (0 0 -1))
|
||||
((0.6 0.35 1.45) (0 0 -1))
|
||||
);
|
||||
position (0.3 0.35 1.45);
|
||||
direction (0 0 -1);
|
||||
|
||||
massTotal 10;
|
||||
parcelsPerInjector 20000;
|
||||
parcelsPerSecond 500;
|
||||
parcelsPerSecond 1000;
|
||||
parcelBasisType mass;
|
||||
flowRateProfile constant 0.1;
|
||||
Umag constant 3.0;
|
||||
@ -104,6 +100,12 @@ subModels
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
model2
|
||||
{
|
||||
$model1;
|
||||
position (0.6 0.35 1.45);
|
||||
}
|
||||
}
|
||||
|
||||
dispersionModel none;
|
||||
|
||||
@ -78,14 +78,14 @@ subModels
|
||||
{
|
||||
model1
|
||||
{
|
||||
type coneNozzleInjection;
|
||||
type coneInjection;
|
||||
SOI 0;
|
||||
massTotal 6.0e-6;
|
||||
parcelBasisType mass;
|
||||
injectionMethod disc;
|
||||
flowType flowRateAndDischarge;
|
||||
outerDiameter 1.9e-4;
|
||||
innerDiameter 0;
|
||||
dInner 0;
|
||||
dOuter 1.9e-4;
|
||||
duration 1.25e-3;
|
||||
position (0 0.0995 0);
|
||||
direction (0 -1 0);
|
||||
|
||||
Reference in New Issue
Block a user