diff --git a/src/OpenFOAM/db/dictionary/dictionary.C b/src/OpenFOAM/db/dictionary/dictionary.C index 5e67648d17..40abb17d47 100644 --- a/src/OpenFOAM/db/dictionary/dictionary.C +++ b/src/OpenFOAM/db/dictionary/dictionary.C @@ -465,7 +465,8 @@ const Foam::entry* Foam::dictionary::lookupScopedEntryPtr *this ) << "keyword " << keyword << " is undefined in dictionary " - << name() + << name() << endl + << "Valid keywords are " << keys() << exit(FatalIOError); } if (!entPtr->isDict()) diff --git a/src/finiteVolume/fields/fvPatchFields/derived/uniformTotalPressure/uniformTotalPressureFvPatchScalarField.C b/src/finiteVolume/fields/fvPatchFields/derived/uniformTotalPressure/uniformTotalPressureFvPatchScalarField.C index e9bd327072..c3b35384cd 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/uniformTotalPressure/uniformTotalPressureFvPatchScalarField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/uniformTotalPressure/uniformTotalPressureFvPatchScalarField.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -44,7 +44,6 @@ uniformTotalPressureFvPatchScalarField rhoName_("none"), psiName_("none"), gamma_(0.0), - p0_(0.0), pressure_() {} @@ -63,7 +62,6 @@ uniformTotalPressureFvPatchScalarField rhoName_(dict.lookupOrDefault("rho", "none")), psiName_(dict.lookupOrDefault("psi", "none")), gamma_(readScalar(dict.lookup("gamma"))), - p0_(readScalar(dict.lookup("p0"))), pressure_(DataEntry::New("pressure", dict)) { if (dict.found("value")) @@ -75,7 +73,8 @@ uniformTotalPressureFvPatchScalarField } else { - fvPatchField::operator=(p0_); + scalar p0 = pressure_->value(this->db().time().timeOutputValue()); + fvPatchField::operator=(p0); } } @@ -95,7 +94,6 @@ uniformTotalPressureFvPatchScalarField rhoName_(ptf.rhoName_), psiName_(ptf.psiName_), gamma_(ptf.gamma_), - p0_(ptf.p0_), pressure_(ptf.pressure_().clone().ptr()) {} @@ -112,7 +110,6 @@ uniformTotalPressureFvPatchScalarField rhoName_(tppsf.rhoName_), psiName_(tppsf.psiName_), gamma_(tppsf.gamma_), - p0_(tppsf.p0_), pressure_(tppsf.pressure_().clone().ptr()) {} @@ -130,7 +127,6 @@ uniformTotalPressureFvPatchScalarField rhoName_(tppsf.rhoName_), psiName_(tppsf.psiName_), gamma_(tppsf.gamma_), - p0_(tppsf.p0_), pressure_(tppsf.pressure_().clone().ptr()) {} @@ -147,14 +143,14 @@ void Foam::uniformTotalPressureFvPatchScalarField::updateCoeffs return; } - p0_ = pressure_->value(this->db().time().timeOutputValue()); + scalar p0 = pressure_->value(this->db().time().timeOutputValue()); const fvsPatchField& phip = patch().lookupPatchField(phiName_); if (psiName_ == "none" && rhoName_ == "none") { - operator==(p0_ - 0.5*(1.0 - pos(phip))*magSqr(Up)); + operator==(p0 - 0.5*(1.0 - pos(phip))*magSqr(Up)); } else if (rhoName_ == "none") { @@ -167,7 +163,7 @@ void Foam::uniformTotalPressureFvPatchScalarField::updateCoeffs operator== ( - p0_ + p0 /pow ( (1.0 + 0.5*psip*gM1ByG*(1.0 - pos(phip))*magSqr(Up)), @@ -177,7 +173,7 @@ void Foam::uniformTotalPressureFvPatchScalarField::updateCoeffs } else { - operator==(p0_/(1.0 + 0.5*psip*(1.0 - pos(phip))*magSqr(Up))); + operator==(p0/(1.0 + 0.5*psip*(1.0 - pos(phip))*magSqr(Up))); } } else if (psiName_ == "none") @@ -185,7 +181,7 @@ void Foam::uniformTotalPressureFvPatchScalarField::updateCoeffs const fvPatchField& rho = patch().lookupPatchField(rhoName_); - operator==(p0_ - 0.5*rho*(1.0 - pos(phip))*magSqr(Up)); + operator==(p0 - 0.5*rho*(1.0 - pos(phip))*magSqr(Up)); } else { @@ -219,7 +215,6 @@ void Foam::uniformTotalPressureFvPatchScalarField::write(Ostream& os) const os.writeKeyword("rho") << rhoName_ << token::END_STATEMENT << nl; os.writeKeyword("psi") << psiName_ << token::END_STATEMENT << nl; os.writeKeyword("gamma") << gamma_ << token::END_STATEMENT << nl; - os.writeKeyword("p0") << p0_ << token::END_STATEMENT << nl; pressure_->writeData(os); writeEntry("value", os); } diff --git a/src/finiteVolume/fields/fvPatchFields/derived/uniformTotalPressure/uniformTotalPressureFvPatchScalarField.H b/src/finiteVolume/fields/fvPatchFields/derived/uniformTotalPressure/uniformTotalPressureFvPatchScalarField.H index aa77ffe2ca..325ed6e471 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/uniformTotalPressure/uniformTotalPressureFvPatchScalarField.H +++ b/src/finiteVolume/fields/fvPatchFields/derived/uniformTotalPressure/uniformTotalPressureFvPatchScalarField.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -75,9 +75,6 @@ class uniformTotalPressureFvPatchScalarField //- Heat capacity ratio scalar gamma_; - //- Total pressure - scalar p0_; - //- Table of time vs total pressure, including the bounding treatment autoPtr > pressure_; @@ -178,18 +175,6 @@ public: return gamma_; } - //- Return the total pressure - scalar p0() const - { - return p0_; - } - - //- Return reference to the total pressure to allow adjustment - scalar p0() - { - return p0_; - } - // Evaluation functions diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H index 321fba33ad..29e696dc81 100644 --- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H +++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.H @@ -470,8 +470,8 @@ public: //- Total rotational kinetic energy in the system inline scalar rotationalKineticEnergyOfSystem() const; - //- Penetration for percentage of the current total mass - inline scalar penetration(const scalar& prc) const; + //- Penetration for fraction [0-1] of the current total mass + inline scalar penetration(const scalar& fraction) const; //- Mean diameter Dij inline scalar Dij(const label i, const label j) const; diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H index a6bdf47cc4..2e793ac71e 100644 --- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H +++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloudI.H @@ -24,6 +24,7 @@ License \*---------------------------------------------------------------------------*/ #include "fvmSup.H" +#include "SortableList.H" // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // @@ -336,106 +337,130 @@ inline Foam::scalar Foam::KinematicCloud::Dmax() const reduce(d, maxOp()); - return d; + return max(0.0, d); } template inline Foam::scalar Foam::KinematicCloud::penetration ( - const scalar& prc + const scalar& fraction ) const { - scalar distance = 0.0; - scalar mTot = 0.0; - - label np = this->size(); - - // arrays containing the parcels mass and - // distance from injector in ascending order - scalarField mass(np); - scalarField dist(np); - - if (np > 0) + if ((fraction < 0) || (fraction > 1)) { - label n = 0; - - // first arrange the parcels in ascending order - // the first parcel is closest to its injection position - // and the last one is most far away. - forAllConstIter(typename KinematicCloud, *this, iter) - { - const parcelType& p = iter(); - scalar mi = p.nParticle()*p.mass(); - scalar di = mag(p.position() - p.position0()); - mTot += mi; - - // insert at the last place - mass[n] = mi; - dist[n] = di; - - label i = 0; - bool found = false; - - // insert the parcel in the correct place - // and move the others - while ((i < n) && (!found)) - { - if (di < dist[i]) - { - found = true; - for (label j=n; j>i; j--) - { - mass[j] = mass[j-1]; - dist[j] = dist[j-1]; - } - mass[i] = mi; - dist[i] = di; - } - i++; - } - n++; - } + FatalErrorIn + ( + "inline Foam::scalar Foam::KinematicCloud::penetration" + "(" + "const scalar&" + ") const" + ) + << "fraction should be in the range 0 < fraction < 1" + << exit(FatalError); } - reduce(mTot, sumOp()); + scalar distance = 0.0; - if (np > 0) + const label nParcel = this->size(); + globalIndex globalParcels(nParcel); + const label nParcelSum = globalParcels.size(); + + if (nParcelSum == 0) { - scalar mLimit = prc*mTot; - scalar mOff = (1.0 - prc)*mTot; + return distance; + } - if (np > 1) + // lists of parcels mass and distance from initial injection point + List mass(nParcel, 0.0); + List dist(nParcel, 0.0); + + label i = 0; + scalar mSum = 0.0; + forAllConstIter(typename KinematicCloud, *this, iter) + { + const parcelType& p = iter(); + scalar m = p.nParticle()*p.mass(); + scalar d = mag(p.position() - p.position0()); + mSum += m; + + mass[i] = m; + dist[i] = d; + + i++; + } + + // calculate total mass across all processors + reduce(mSum, sumOp()); + + // flatten the mass list + List allMass(nParcelSum, 0.0); + SubList + ( + allMass, + globalParcels.localSize(Pstream::myProcNo()), + globalParcels.offset(Pstream::myProcNo()) + ).assign(mass); + + // flatten the distance list + SortableList allDist(nParcelSum, 0.0); + SubList + ( + allDist, + globalParcels.localSize(Pstream::myProcNo()), + globalParcels.offset(Pstream::myProcNo()) + ).assign(dist); + + // sort allDist distances into ascending order + // note: allMass masses are left unsorted + allDist.sort(); + + if (nParcelSum > 1) + { + const scalar mLimit = fraction*mSum; + const labelList& indices = allDist.indices(); + + if (mLimit > (mSum - allMass[indices.last()])) { - // 'prc' is large enough that the parcel most far - // away will be used, no need to loop... - if (mLimit > mTot - mass[np-1]) - { - distance = dist[np-1]; - } - else - { - scalar mOffSum = 0.0; - label i = np; - - while ((mOffSum < mOff) && (i>0)) - { - i--; - mOffSum += mass[i]; - } - distance = - dist[i+1] - + (dist[i] - dist[i+1])*(mOffSum - mOff) - /mass[i+1] ; - } + distance = allDist.last(); } else { - distance = dist[0]; + // assuming that 'fraction' is generally closer to 1 than 0, loop + // through in reverse distance order + const scalar mThreshold = (1.0 - fraction)*mSum; + scalar mCurrent = 0.0; + label i0 = 0; + + forAllReverse(indices, i) + { + label indI = indices[i]; + + mCurrent += allMass[indI]; + + if (mCurrent > mThreshold) + { + i0 = i; + break; + } + } + + if (i0 == indices.size() - 1) + { + distance = allDist.last(); + } + else + { + // linearly interpolate to determine distance + scalar alpha = (mCurrent - mThreshold)/allMass[indices[i0]]; + distance = allDist[i0] + alpha*(allDist[i0+1] - allDist[i0]); + } } } - - reduce(distance, maxOp()); + else + { + distance = allDist.first(); + } return distance; } diff --git a/src/lagrangian/intermediate/clouds/baseClasses/kinematicCloud/kinematicCloud.H b/src/lagrangian/intermediate/clouds/baseClasses/kinematicCloud/kinematicCloud.H index 01c80c16e2..d7a0fcf0d0 100644 --- a/src/lagrangian/intermediate/clouds/baseClasses/kinematicCloud/kinematicCloud.H +++ b/src/lagrangian/intermediate/clouds/baseClasses/kinematicCloud/kinematicCloud.H @@ -89,7 +89,7 @@ public: virtual scalar rotationalKineticEnergyOfSystem() const = 0; //- Penetration for percentage of the current total mass -// virtual scalar penetration(const scalar& prc) const = 0; +// virtual scalar penetration(const scalar& fraction) const = 0; //- Mean diameter Dij virtual scalar Dij(const label i, const label j) const = 0; diff --git a/src/lagrangian/intermediate/parcels/Templates/ReactingMultiphaseParcel/ReactingMultiphaseParcel.C b/src/lagrangian/intermediate/parcels/Templates/ReactingMultiphaseParcel/ReactingMultiphaseParcel.C index 84942b0349..461ec5b285 100644 --- a/src/lagrangian/intermediate/parcels/Templates/ReactingMultiphaseParcel/ReactingMultiphaseParcel.C +++ b/src/lagrangian/intermediate/parcels/Templates/ReactingMultiphaseParcel/ReactingMultiphaseParcel.C @@ -636,7 +636,7 @@ void Foam::ReactingMultiphaseParcel::calcSurfaceReactions *(sum(dMassSRGas) + sum(dMassSRLiquid) + sum(dMassSRSolid)) ); - const scalar xsi = min(T/5000.0, 1.0); + const scalar xsi = min(T/td.cloud().constProps().TMax(), 1.0); const scalar coeff = (1.0 - xsi*xsi)*td.cloud().constProps().hRetentionCoeff(); diff --git a/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/PressureGradient/PressureGradientForce.C b/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/PressureGradient/PressureGradientForce.C index a1d121ee29..c9d61f6d34 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/PressureGradient/PressureGradientForce.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/PressureGradient/PressureGradientForce.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -24,6 +24,7 @@ License \*---------------------------------------------------------------------------*/ #include "PressureGradientForce.H" +#include "fvcDdt.H" #include "fvcGrad.H" // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // @@ -33,12 +34,13 @@ Foam::PressureGradientForce::PressureGradientForce ( CloudType& owner, const fvMesh& mesh, - const dictionary& dict + const dictionary& dict, + const word& forceType ) : - ParticleForce(owner, mesh, dict, typeName, true), - UName_(this->coeffs().lookup("U")), - gradUPtr_(NULL) + ParticleForce(owner, mesh, dict, forceType, true), + UName_(this->coeffs().template lookupOrDefault("U", "U")), + DUcDtInterpPtr_(NULL) {} @@ -50,7 +52,7 @@ Foam::PressureGradientForce::PressureGradientForce : ParticleForce(pgf), UName_(pgf.UName_), - gradUPtr_(NULL) + DUcDtInterpPtr_(NULL) {} @@ -66,18 +68,48 @@ Foam::PressureGradientForce::~PressureGradientForce() template void Foam::PressureGradientForce::cacheFields(const bool store) { + static word fName("DUcDt"); + + bool fieldExists = this->mesh().template foundObject(fName); + if (store) { - const volVectorField& U = this->mesh().template - lookupObject(UName_); - gradUPtr_ = fvc::grad(U).ptr(); + if (!fieldExists) + { + const volVectorField& Uc = this->mesh().template + lookupObject(UName_); + + volVectorField* DUcDtPtr = new volVectorField + ( + fName, + fvc::ddt(Uc) + (Uc & fvc::grad(Uc)) + ); + + DUcDtPtr->store(); + } + + const volVectorField& DUcDt = this->mesh().template + lookupObject(fName); + + DUcDtInterpPtr_.reset + ( + interpolation::New + ( + this->owner().solution().interpolationSchemes(), + DUcDt + ).ptr() + ); } else { - if (gradUPtr_) + DUcDtInterpPtr_.clear(); + + if (fieldExists) { - delete gradUPtr_; - gradUPtr_ = NULL; + const volVectorField& DUcDt = this->mesh().template + lookupObject(fName); + + const_cast(DUcDt).checkOut(); } } } @@ -95,11 +127,24 @@ Foam::forceSuSp Foam::PressureGradientForce::calcCoupled { forceSuSp value(vector::zero, 0.0); - const volTensorField& gradU = *gradUPtr_; - value.Su() = mass*p.rhoc()/p.rho()*(p.U() & gradU[p.cell()]); + vector DUcDt = + DUcDtInterp().interpolate(p.position(), p.currentTetIndices()); + + value.Su() = mass*p.rhoc()/p.rho()*DUcDt; return value; } +template +Foam::scalar Foam::PressureGradientForce::massAdd +( + const typename CloudType::parcelType&, + const scalar +) const +{ + return 0.0; +} + + // ************************************************************************* // diff --git a/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/PressureGradient/PressureGradientForce.H b/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/PressureGradient/PressureGradientForce.H index 663723a820..b1986348fb 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/PressureGradient/PressureGradientForce.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/PressureGradient/PressureGradientForce.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -38,6 +38,7 @@ SourceFiles #include "ParticleForce.H" #include "volFields.H" +#include "interpolation.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -53,13 +54,15 @@ class PressureGradientForce : public ParticleForce { - // Private data +protected: + + // Protected data //- Name of velocity field const word UName_; - //- Velocity gradient field - const volTensorField* gradUPtr_; + //- Rate of change of carrier phase velocity interpolator + autoPtr > DUcDtInterpPtr_; public: @@ -75,7 +78,8 @@ public: ( CloudType& owner, const fvMesh& mesh, - const dictionary& dict + const dictionary& dict, + const word& forceType = typeName ); //- Construct copy @@ -99,8 +103,8 @@ public: // Access - //- Return const access to the velocity gradient field - inline const volTensorField& gradU() const; + //- Return the rate of change of carrier phase velocity interpolator + inline const interpolation& DUcDtInterp() const; // Evaluation @@ -117,6 +121,13 @@ public: const scalar Re, const scalar muc ) const; + + //- Return the added mass + virtual scalar massAdd + ( + const typename CloudType::parcelType& p, + const scalar mass + ) const; }; diff --git a/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/PressureGradient/PressureGradientForceI.H b/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/PressureGradient/PressureGradientForceI.H index c9bd24c62c..6c085241de 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/PressureGradient/PressureGradientForceI.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/PressureGradient/PressureGradientForceI.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -26,23 +26,20 @@ License // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // template -const Foam::volTensorField& Foam::PressureGradientForce::gradU() -const +inline const Foam::interpolation& +Foam::PressureGradientForce::DUcDtInterp() const { - if (gradUPtr_) - { - return *gradUPtr_; - } - else + if (!DUcDtInterpPtr_.valid()) { FatalErrorIn ( - "const volTensorField& PressureGradientForce::gradU()" - "const" - ) << "gradU field not allocated" << abort(FatalError); - - return *reinterpret_cast(0); + "inline const Foam::interpolation&" + "Foam::PressureGradientForce::DUcDtInterp() const" + ) << "Carrier phase DUcDt interpolation object not set" + << abort(FatalError); } + + return DUcDtInterpPtr_(); } diff --git a/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/VirtualMass/VirtualMassForce.C b/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/VirtualMass/VirtualMassForce.C index 3dca602dd4..c701e07a00 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/VirtualMass/VirtualMassForce.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/VirtualMass/VirtualMassForce.C @@ -24,8 +24,6 @@ License \*---------------------------------------------------------------------------*/ #include "VirtualMassForce.H" -#include "fvcDdt.H" -#include "fvcGrad.H" // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // @@ -34,14 +32,12 @@ Foam::VirtualMassForce::VirtualMassForce ( CloudType& owner, const fvMesh& mesh, - const dictionary& dict + const dictionary& dict, + const word& forceType ) : - ParticleForce(owner, mesh, dict, typeName, true), - UName_(this->coeffs().template lookupOrDefault("U", "U")), - Cvm_(readScalar(this->coeffs().lookup("Cvm"))), - DUcDtPtr_(NULL), - DUcDtInterpPtr_(NULL) + PressureGradientForce(owner, mesh, dict, forceType), + Cvm_(readScalar(this->coeffs().lookup("Cvm"))) {} @@ -51,11 +47,8 @@ Foam::VirtualMassForce::VirtualMassForce const VirtualMassForce& vmf ) : - ParticleForce(vmf), - UName_(vmf.UName_), - Cvm_(vmf.Cvm_), - DUcDtPtr_(NULL), - DUcDtInterpPtr_(NULL) + PressureGradientForce(vmf), + Cvm_(vmf.Cvm_) {} @@ -71,36 +64,7 @@ Foam::VirtualMassForce::~VirtualMassForce() template void Foam::VirtualMassForce::cacheFields(const bool store) { - if (store && !DUcDtPtr_) - { - const volVectorField& Uc = this->mesh().template - lookupObject(UName_); - - DUcDtPtr_ = new volVectorField - ( - "DUcDt", - fvc::ddt(Uc) + (Uc & fvc::grad(Uc)) - ); - - DUcDtInterpPtr_.reset - ( - interpolation::New - ( - this->owner().solution().interpolationSchemes(), - *DUcDtPtr_ - ).ptr() - ); - } - else - { - DUcDtInterpPtr_.clear(); - - if (DUcDtPtr_) - { - delete DUcDtPtr_; - DUcDtPtr_ = NULL; - } - } + PressureGradientForce::cacheFields(store); } @@ -114,12 +78,10 @@ Foam::forceSuSp Foam::VirtualMassForce::calcCoupled const scalar muc ) const { - forceSuSp value(vector::zero, 0.0); + forceSuSp value = + PressureGradientForce::calcCoupled(p, dt, mass, Re, muc); - vector DUcDt = - DUcDtInterp().interpolate(p.position(), p.currentTetIndices()); - - value.Su() = mass*p.rhoc()/p.rho()*Cvm_*DUcDt; + value.Su() *= Cvm_; return value; } diff --git a/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/VirtualMass/VirtualMassForce.H b/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/VirtualMass/VirtualMassForce.H index c5277ec696..ea0d580932 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/VirtualMass/VirtualMassForce.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/VirtualMass/VirtualMassForce.H @@ -28,7 +28,6 @@ Description Calculates particle virtual mass force SourceFiles - VirtualMassForceI.H VirtualMassForce.C \*---------------------------------------------------------------------------*/ @@ -36,9 +35,7 @@ SourceFiles #ifndef VirtualMassForce_H #define VirtualMassForce_H -#include "ParticleForce.H" -#include "volFields.H" -#include "interpolation.H" +#include "PressureGradientForce.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -52,22 +49,13 @@ namespace Foam template class VirtualMassForce : - public ParticleForce + public PressureGradientForce { // Private data - //- Name of velocity field - const word UName_; - //- Virtual mass coefficient - typically 0.5 scalar Cvm_; - //- Rate of change of carrier phase velocity - volVectorField* DUcDtPtr_; - - //- Rate of change of carrier phase velocity interpolator - autoPtr > DUcDtInterpPtr_; - public: @@ -82,7 +70,8 @@ public: ( CloudType& owner, const fvMesh& mesh, - const dictionary& dict + const dictionary& dict, + const word& forceType = typeName ); //- Construct copy @@ -104,15 +93,6 @@ public: // Member Functions - // Access - - //- Return the rate of change of carrier phase velocity - inline const volVectorField& DUcDt() const; - - //- Return the rate of change of carrier phase velocity interpolator - inline const interpolation& DUcDtInterp() const; - - // Evaluation //- Cache fields @@ -143,8 +123,6 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -#include "VirtualMassForceI.H" - #ifdef NoRepository #include "VirtualMassForce.C" #endif diff --git a/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/VirtualMass/VirtualMassForceI.H b/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/VirtualMass/VirtualMassForceI.H deleted file mode 100644 index e156c58d14..0000000000 --- a/src/lagrangian/intermediate/submodels/Kinematic/ParticleForces/VirtualMass/VirtualMassForceI.H +++ /dev/null @@ -1,66 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 2012 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 . - -\*---------------------------------------------------------------------------*/ - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -template -const Foam::volVectorField& Foam::VirtualMassForce::DUcDt() const -{ - if (DUcDtPtr_) - { - return *DUcDtPtr_; - } - else - { - FatalErrorIn - ( - "const volVectorField& VirtualMassForce::DUcDt()" - "const" - ) << "DUcDt field not allocated" << abort(FatalError); - - return *reinterpret_cast(0); - } -} - - -template -inline const Foam::interpolation& -Foam::VirtualMassForce::DUcDtInterp() const -{ - if (!DUcDtInterpPtr_.valid()) - { - FatalErrorIn - ( - "inline const Foam::interpolation&" - "Foam::VirtualMassForce::DUcDtInterp() const" - ) << "Carrier pahase DUcDt interpolation object not set" - << abort(FatalError); - } - - return DUcDtInterpPtr_(); -} - - -// ************************************************************************* // diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C index abe3bc487c..26b4fb0187 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C @@ -48,6 +48,10 @@ Description #include "globalIndex.H" #include "DynamicField.H" #include "PatchTools.H" +#include "slipPointPatchFields.H" +#include "fixedValuePointPatchFields.H" +#include "calculatedPointPatchFields.H" +#include "cyclicSlipPointPatchFields.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -71,7 +75,7 @@ void Foam::autoLayerDriver::dumpDisplacement ) { OFstream dispStr(prefix + "_disp.obj"); - Info<< "Writing all displacements to " << dispStr.name() << nl << endl; + Info<< "Writing all displacements to " << dispStr.name() << endl; label vertI = 0; @@ -87,7 +91,7 @@ void Foam::autoLayerDriver::dumpDisplacement OFstream illStr(prefix + "_illegal.obj"); - Info<< "Writing invalid displacements to " << illStr.name() << nl << endl; + Info<< "Writing invalid displacements to " << illStr.name() << endl; vertI = 0; @@ -801,6 +805,81 @@ void Foam::autoLayerDriver::setNumLayers } +// Construct pointVectorField with correct boundary conditions for adding +// layers +Foam::tmp +Foam::autoLayerDriver::makeLayerDisplacementField +( + const pointMesh& pMesh, + const labelList& numLayers +) +{ + // Construct displacement field. + const pointBoundaryMesh& pointPatches = pMesh.boundary(); + + wordList patchFieldTypes + ( + pointPatches.size(), + slipPointPatchVectorField::typeName + ); + + forAll(numLayers, patchI) + { + // 0 layers: do not allow lslip so fixedValue 0 + // >0 layers: fixedValue which gets adapted + if (numLayers[patchI] >= 0) + { + patchFieldTypes[patchI] = fixedValuePointPatchVectorField::typeName; + } + } + + forAll(pointPatches, patchI) + { + if (isA(pointPatches[patchI])) + { + patchFieldTypes[patchI] = calculatedPointPatchVectorField::typeName; + } + else if (isA(pointPatches[patchI])) + { + patchFieldTypes[patchI] = cyclicSlipPointPatchVectorField::typeName; + } + } + + +//Pout<< "*** makeLayerDisplacementField : boundary conditions:" << endl; +//forAll(patchFieldTypes, patchI) +//{ +// Pout<< "\t" << patchI << " name:" << pointPatches[patchI].name() +// << " type:" << patchFieldTypes[patchI] +// << " nLayers:" << numLayers[patchI] +// << endl; +//} + + const polyMesh& mesh = pMesh(); + + // Note: time().timeName() instead of meshRefinement::timeName() since + // postprocessable field. + tmp tfld + ( + new pointVectorField + ( + IOobject + ( + "pointDisplacement", + mesh.time().timeName(), + mesh, + IOobject::NO_READ, + IOobject::AUTO_WRITE + ), + pMesh, + dimensionedVector("displacement", dimLength, vector::zero), + patchFieldTypes + ) + ); + return tfld; +} + + void Foam::autoLayerDriver::growNoExtrusion ( const indirectPrimitivePatch& pp, @@ -2392,10 +2471,10 @@ void Foam::autoLayerDriver::addLayers mesh, pp(), patchIDs, - meshRefinement::makeDisplacementField + makeLayerDisplacementField ( pointMesh::New(mesh), - patchIDs + layerParams.numLayers() ), motionDict ) @@ -3186,7 +3265,7 @@ void Foam::autoLayerDriver::doLayers // Merge coplanar boundary faces mergePatchFacesUndo(layerParams, motionDict); - // Per patch the number of layers (0 if no layer) + // Per patch the number of layers (-1 or 0 if no layer) const labelList& numLayers = layerParams.numLayers(); // Patches that need to get a layer diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H index cb720dc64f..d36d15a4cb 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.H @@ -195,6 +195,19 @@ class autoLayerDriver List& extrudeStatus ) const; + //- Helper function to make a pointVectorField with correct + // bcs for layer addition: + // - numLayers > 0 : fixedValue + // - numLayers == 0 : fixedValue (always zero) + // - processor : calculated (so free to move) + // - cyclic/wedge/symmetry : slip + // - other : slip + static tmp makeLayerDisplacementField + ( + const pointMesh& pMesh, + const labelList& numLayers + ); + //- Grow no-extrusion layer. void growNoExtrusion ( @@ -444,7 +457,6 @@ class autoLayerDriver const PackedBoolList& isMasterEdge, const labelList& meshEdges, const scalar minCosLayerTermination, - scalarField& field, List& extrudeStatus, pointField& patchDisp, labelList& patchNLayers diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C index 35133f062d..58725470e1 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C @@ -99,6 +99,76 @@ void Foam::autoLayerDriver::sumWeights // Smooth field on moving patch +//void Foam::autoLayerDriver::smoothField +//( +// const motionSmoother& meshMover, +// const PackedBoolList& isMasterEdge, +// const labelList& meshEdges, +// const scalarField& fieldMin, +// const label nSmoothDisp, +// scalarField& field +//) const +//{ +// const indirectPrimitivePatch& pp = meshMover.patch(); +// const edgeList& edges = pp.edges(); +// const labelList& meshPoints = pp.meshPoints(); +// +// scalarField invSumWeight(pp.nPoints()); +// sumWeights +// ( +// isMasterEdge, +// meshEdges, +// meshPoints, +// edges, +// invSumWeight +// ); +// +// // Get smoothly varying patch field. +// Info<< "shrinkMeshDistance : Smoothing field ..." << endl; +// +// for (label iter = 0; iter < nSmoothDisp; iter++) +// { +// scalarField average(pp.nPoints()); +// averageNeighbours +// ( +// meshMover.mesh(), +// isMasterEdge, +// meshEdges, +// meshPoints, +// pp.edges(), +// invSumWeight, +// field, +// average +// ); +// +// // Transfer to field +// forAll(field, pointI) +// { +// //full smoothing neighbours + point value +// average[pointI] = 0.5*(field[pointI]+average[pointI]); +// +// // perform monotonic smoothing +// if +// ( +// average[pointI] < field[pointI] +// && average[pointI] >= fieldMin[pointI] +// ) +// { +// field[pointI] = average[pointI]; +// } +// } +// +// // Do residual calculation every so often. +// if ((iter % 10) == 0) +// { +// Info<< " Iteration " << iter << " residual " +// << gSum(mag(field-average)) +// /returnReduce(average.size(), sumOp