Commit 0260643c authored by Andrew Heather's avatar Andrew Heather Committed by Andrew Heather
Browse files

ENH: PatchInjectionModel - added new parcel initial velocity options

The parcel initial velocity can now be set using the new `velocityType`
entry, taking one of the following options:

- fixedValue   : (default) same as earlier versions, requires U0
- patchValue   : velocity set to seed patch face value
- zeroGradient : velocity set to seed patch face adjacent cell value

Example usage:

        model1
        {
            type            patchInjection;
            massTotal       1;
            SOI             0;
            parcelBasisType mass;
            patch           cylinder;
            duration        10;
            parcelsPerSecond 100;
            velocityType    patchValue;
            //velocityType    zeroGradient;
            //U0              (-10 0 0);
            flowRateProfile constant 1;
            sizeDistribution
            {
                type        normal;
                normalDistribution
                {
                    expectation 1e-3;
                    variance 1e-4;
                    minValue 1e-5;
                    maxValue 2e-3;
                }
            }
        }

See the new $FOAM_TUTORIALS/lagrangian/kinematicParcelFoam/spinningDisk tutorial
parent 0e7920ef
......@@ -29,6 +29,17 @@ License
#include "PatchInjection.H"
#include "distributionModel.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
template<class CloudType>
const Foam::Enum<typename Foam::PatchInjection<CloudType>::velocityType>
Foam::PatchInjection<CloudType>::velocityTypeNames_
({
{ vtFixedValue, "fixedValue" },
{ vtPatchValue, "patchValue" },
{ vtZeroGradient, "zeroGradient" },
});
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class CloudType>
......@@ -46,7 +57,21 @@ Foam::PatchInjection<CloudType>::PatchInjection
(
this->coeffDict().getScalar("parcelsPerSecond")
),
U0_(this->coeffDict().lookup("U0")),
velocityType_
(
velocityTypeNames_.getOrDefault
(
"velocityType",
this->coeffDict(),
vtFixedValue
)
),
U0_
(
velocityType_ == vtFixedValue
? this->coeffDict().template get<vector>("U0")
: Zero
),
flowRateProfile_
(
Function1<scalar>::New
......@@ -63,7 +88,9 @@ Foam::PatchInjection<CloudType>::PatchInjection
this->coeffDict().subDict("sizeDistribution"),
owner.rndGen()
)
)
),
currentParceli_(-1),
currentFacei_(-1)
{
// Convert from user time to reduce the number of time conversion calls
const Time& time = owner.db().time();
......@@ -87,16 +114,12 @@ Foam::PatchInjection<CloudType>::PatchInjection
patchInjectionBase(im),
duration_(im.duration_),
parcelsPerSecond_(im.parcelsPerSecond_),
velocityType_(im.velocityType_),
U0_(im.U0_),
flowRateProfile_(im.flowRateProfile_.clone()),
sizeDistribution_(im.sizeDistribution_.clone())
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class CloudType>
Foam::PatchInjection<CloudType>::~PatchInjection()
sizeDistribution_(im.sizeDistribution_.clone()),
currentParceli_(im.currentParceli_),
currentFacei_(im.currentFacei_)
{}
......@@ -167,16 +190,18 @@ Foam::scalar Foam::PatchInjection<CloudType>::volumeToInject
template<class CloudType>
void Foam::PatchInjection<CloudType>::setPositionAndCell
(
const label,
const label,
const scalar,
const label parcelI,
const label nParcels,
const scalar time,
vector& position,
label& cellOwner,
label& tetFacei,
label& tetPti
)
{
patchInjectionBase::setPositionAndCell
currentParceli_ = parcelI;
currentFacei_ = patchInjectionBase::setPositionAndCell
(
this->owner().mesh(),
this->owner().rndGen(),
......@@ -191,16 +216,74 @@ void Foam::PatchInjection<CloudType>::setPositionAndCell
template<class CloudType>
void Foam::PatchInjection<CloudType>::setProperties
(
const label,
const label,
const scalar,
const label parcelI,
const label nParcels,
const scalar time,
typename CloudType::parcelType& parcel
)
{
// set particle velocity
parcel.U() = U0_;
// Set particle velocity
switch (velocityType_)
{
case vtFixedValue:
{
parcel.U() = U0_;
break;
}
case vtPatchValue:
{
if (parcelI != currentParceli_)
{
WarningInFunction
<< "Synchronisation problem: "
<< "attempting to set injected parcel " << parcelI
<< " properties using cached parcel " << currentParceli_
<< " properties" << endl;
}
const label patchFacei = currentFacei_;
if (patchFacei < 0)
{
FatalErrorInFunction
<< "Unable to set parcel velocity using patch value "
<< "due to missing face index: patchFacei=" << patchFacei
<< abort(FatalError);
}
const volVectorField& U = this->owner().U();
const label patchi = this->patchId_;
parcel.U() = U.boundaryField()[patchi][patchFacei];
break;
}
case vtZeroGradient:
{
const label celli = parcel.cell();
if (celli < 0)
{
FatalErrorInFunction
<< "Unable to set parcel velocity using zeroGradient "
<< "due to missing cell index"
<< abort(FatalError);
}
const volVectorField& U = this->owner().U();
parcel.U() = U[celli];
break;
}
default:
{
FatalErrorInFunction
<< "Unhandled velocityType "
<< velocityTypeNames_[velocityType_]
<< ". Available options are:"
<< velocityTypeNames_.sortedToc()
<< abort(FatalError);
}
}
// set particle diameter
// Set particle diameter
parcel.d() = sizeDistribution_->sample();
}
......
......@@ -72,6 +72,24 @@ class PatchInjection
public InjectionModel<CloudType>,
public patchInjectionBase
{
public:
// Public Data Types
//- Velocity type enumeration
enum velocityType
{
vtFixedValue, //!< User supplied fixed value
vtPatchValue, //!< Patch face values
vtZeroGradient //!< Patch internal cell values
};
//- Velocity type names
static const Enum<velocityType> velocityTypeNames_;
private:
// Private data
//- Injection duration [s]
......@@ -80,7 +98,11 @@ class PatchInjection
//- Number of parcels to introduce per second []
const label parcelsPerSecond_;
//- Velocity type
const velocityType velocityType_;
//- Initial parcel velocity [m/s]
// Note: Only used for vtFixedValue
const vector U0_;
//- Flow rate profile relative to SOI []
......@@ -89,6 +111,12 @@ class PatchInjection
//- Parcel size distribution model
const autoPtr<distributionModel> sizeDistribution_;
//- Current parcel being processed
label currentParceli_;
//- Current face being processed
label currentFacei_;
public:
......@@ -120,7 +148,7 @@ public:
//- Destructor
virtual ~PatchInjection();
virtual ~PatchInjection() = default;
// Member Functions
......
......@@ -144,7 +144,7 @@ void Foam::patchInjectionBase::updateMesh(const polyMesh& mesh)
}
void Foam::patchInjectionBase::setPositionAndCell
Foam::label Foam::patchInjectionBase::setPositionAndCell
(
const fvMesh& mesh,
const scalar fraction01,
......@@ -155,6 +155,8 @@ void Foam::patchInjectionBase::setPositionAndCell
label& tetPti
)
{
label facei = -1;
if (cellOwners_.size() > 0)
{
// Determine which processor to inject from
......@@ -177,7 +179,7 @@ void Foam::patchInjectionBase::setPositionAndCell
}
// Set cellOwner
label facei = triToFace_[trii];
facei = triToFace_[trii];
cellOwner = cellOwners_[facei];
// Find random point in triangle
......@@ -261,10 +263,12 @@ void Foam::patchInjectionBase::setPositionAndCell
// Dummy position
position = pTraits<vector>::max;
}
return facei;
}
void Foam::patchInjectionBase::setPositionAndCell
Foam::label Foam::patchInjectionBase::setPositionAndCell
(
const fvMesh& mesh,
Random& rnd,
......@@ -276,7 +280,7 @@ void Foam::patchInjectionBase::setPositionAndCell
{
scalar fraction01 = rnd.globalSample01<scalar>();
setPositionAndCell
return setPositionAndCell
(
mesh,
fraction01,
......
......@@ -118,7 +118,8 @@ public:
//- Set the injection position and owner cell, tetFace and tetPt
// Supply the fraction used to determine the location on the patch
void setPositionAndCell
// Returns the seed patch face index
label setPositionAndCell
(
const fvMesh& mesh,
const scalar fraction01,
......@@ -130,7 +131,8 @@ public:
);
//- Set the injection position and owner cell, tetFace and tetPt
virtual void setPositionAndCell
// Returns the seed patch face index
virtual label setPositionAndCell
(
const fvMesh& mesh,
Random& rnd,
......
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2106 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -1 0 0 0 0];
internalField uniform (0.1 0 0);
boundaryField
{
inlet
{
type fixedValue;
value $internalField;
}
outlet
{
type inletOutlet;
inletValue uniform (0 0 0);
value uniform (0 0 0);
}
cylinder
{
type rotatingWallVelocity;
origin (0 0 0);
axis (0 0 1);
omega 1;
}
walls
{
type noSlip;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2106 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object p;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -2 0 0 0 0];
internalField uniform 0;
boundaryField
{
inlet
{
type zeroGradient;
}
outlet
{
type fixedValue;
value uniform 0;
}
"(walls|cylinder)"
{
type zeroGradient;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2106 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class uniformDimensionedVectorField;
object g;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -2 0 0 0 0];
value (0 0 -9.8);
// ************************************************************************* //
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1912 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object kinematicCloudProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
solution
{
active true;
coupled yes;
transient yes;
cellValueSourceCorrection no;
maxCo 0.3;
sourceTerms
{
schemes
{
U semiImplicit 1;
}
}
interpolationSchemes
{
rho cell;
U cellPoint;
muc cell;
p cell;
}
integrationSchemes
{
U Euler;
}
}
constantProperties
{
rho0 1000;
}
subModels
{
particleForces
{
sphereDrag;
gravity;
}
injectionModels
{
model1
{
type patchInjection;
massTotal 1;
SOI 0;
parcelBasisType mass;
patch cylinder;
duration 10;
parcelsPerSecond 100;
velocityType patchValue;
//velocityType zeroGradient;
//U0 (-10 0 0);
flowRateProfile constant 1;
sizeDistribution
{
type normal;
normalDistribution
{
expectation 1e-3;
variance 1e-4;
minValue 1e-5;
maxValue 2e-3;
}
}
}
}
dispersionModel none;
patchInteractionModel standardWallInteraction;
stochasticCollisionModel none;
surfaceFilmModel none;
standardWallInteractionCoeffs
{
type rebound;
}
}
cloudFunctions
{}
// ************************************************************************* //
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2106 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object transportProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
transportModel Newtonian;
nu 1e-05;
rhoInf 1.2;
// ************************************************************************* //
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2106 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object turbulenceProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
simulationType laminar;
// ************************************************************************* //
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2106 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;