diff --git a/src/lagrangian/intermediate/parcels/include/makeParcelCollisionModels.H b/src/lagrangian/intermediate/parcels/include/makeParcelCollisionModels.H index 9160c3db85..afdb46430f 100644 --- a/src/lagrangian/intermediate/parcels/include/makeParcelCollisionModels.H +++ b/src/lagrangian/intermediate/parcels/include/makeParcelCollisionModels.H @@ -34,7 +34,9 @@ License #include "NoCollision.H" #include "PairCollision.H" -#include "SpringSliderDashpot.H" +#include "PairSpringSliderDashpot.H" + +#include "WallSpringSliderDashpot.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -60,7 +62,16 @@ License \ makePairModelType \ ( \ - SpringSliderDashpot, \ + PairSpringSliderDashpot, \ + InteractingKinematicCloud, \ + ParcelType \ + ); \ + \ + makeWallModel(InteractingKinematicCloud); \ + \ + makeWallModelType \ + ( \ + WallSpringSliderDashpot, \ InteractingKinematicCloud, \ ParcelType \ ); diff --git a/src/lagrangian/intermediate/parcels/include/makeReactingParcelCollisionModels.H b/src/lagrangian/intermediate/parcels/include/makeReactingParcelCollisionModels.H index 113ee7b170..05a702020c 100644 --- a/src/lagrangian/intermediate/parcels/include/makeReactingParcelCollisionModels.H +++ b/src/lagrangian/intermediate/parcels/include/makeReactingParcelCollisionModels.H @@ -35,7 +35,9 @@ License #include "NoCollision.H" #include "PairCollision.H" -#include "SpringSliderDashpot.H" +#include "PairSpringSliderDashpot.H" + +#include "WallSpringSliderDashpot.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -84,7 +86,17 @@ License \ makePairModelThermoType \ ( \ - SpringSliderDashpot, \ + PairSpringSliderDashpot, \ + InteractingKinematicCloud, \ + ParcelType, \ + ThermoType \ + ); \ + \ + makeWallModel(InteractingKinematicCloud >); \ + \ + makeWallModelThermoType \ + ( \ + WallSpringSliderDashpot, \ InteractingKinematicCloud, \ ParcelType, \ ThermoType \ diff --git a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairCollision.C b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairCollision.C index 3be79ab797..aa0ea25b53 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairCollision.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairCollision.C @@ -26,6 +26,17 @@ License #include "PairCollision.H" #include "PairModel.H" +#include "WallModel.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +template +Foam::scalar Foam::PairCollision::cosPhiMinFlatWall = 1 - 1e-6; + +template +Foam::scalar Foam::PairCollision::flatWallDuplicateExclusion = + sqrt(3e-6); + // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // @@ -144,11 +155,15 @@ void Foam::PairCollision::wallInteraction() const DirectInteractionList& dil = il_.dil(); - ReferredCellList& ril = il_.ril(); + const ReferredCellList& ril = il_.ril(); - DynamicList allWallInteractionSites; - DynamicList flatWallInteractionSites; - DynamicList sharpWallInteractionSites; + // Storage for the wall interaction sites + DynamicList flatSites; + DynamicList flatSiteExclusionDistancesSqr; + DynamicList otherSites; + DynamicList otherSiteDistances; + DynamicList sharpSites; + DynamicList sharpSiteExclusionDistancesSqr; forAll(dil, realCellI) { @@ -162,14 +177,17 @@ void Foam::PairCollision::wallInteraction() // Loop over all Parcels in cell forAll(cellOccupancy_[realCellI], cellParticleI) { - allWallInteractionSites.clear(); - flatWallInteractionSites.clear(); - sharpWallInteractionSites.clear(); + flatSites.clear(); + flatSiteExclusionDistancesSqr.clear(); + otherSites.clear(); + otherSiteDistances.clear(); + sharpSites.clear(); + sharpSiteExclusionDistancesSqr.clear(); typename CloudType::parcelType& p = *cellOccupancy_[realCellI][cellParticleI]; - const point& pt = p.position(); + const point& pos = p.position(); // real wallFace interactions @@ -179,7 +197,7 @@ void Foam::PairCollision::wallInteraction() pointHit nearest = mesh.faces()[realFaceI].nearestPoint ( - pt, + pos, mesh.points() ); @@ -189,15 +207,41 @@ void Foam::PairCollision::wallInteraction() normal /= mag(normal); - vector pW = nearest.rawPoint() - pt; + const vector& nearPt = nearest.rawPoint(); + + vector pW = nearPt - pos; scalar normalAlignment = normal & pW/mag(pW); - allWallInteractionSites.append(nearest.rawPoint()); - - if (normalAlignment > 1 - SMALL) + if (normalAlignment > cosPhiMinFlatWall) { - flatWallInteractionSites.append(nearest.rawPoint()); + // Guard against a flat interaction being + // present on the boundary of two or more + // faces, which would create duplicate contact + // points. Duplicates are discarded. + if + ( + !duplicatePointInList + ( + flatSites, + nearPt, + sqr(p.r()*flatWallDuplicateExclusion) + ) + ) + { + flatSites.append(nearPt); + + flatSiteExclusionDistancesSqr.append + ( + sqr(p.r()) - sqr(nearest.distance()) + ); + } + } + else + { + otherSites.append(nearPt); + + otherSiteDistances.append(nearest.distance()); } } } @@ -206,7 +250,7 @@ void Foam::PairCollision::wallInteraction() forAll(referredCellsInRange, refCellInRangeI) { - ReferredCell& refCell = + const ReferredCell& refCell = ril[referredCellsInRange[refCellInRangeI]]; const labelList& refWallFaces = refCell.wallFaces(); @@ -217,7 +261,7 @@ void Foam::PairCollision::wallInteraction() pointHit nearest = refCell.faces()[refFaceI].nearestPoint ( - pt, + pos, refCell.points() ); @@ -227,56 +271,144 @@ void Foam::PairCollision::wallInteraction() normal /= mag(normal); - vector pW = nearest.rawPoint() - pt; + const vector& nearPt = nearest.rawPoint(); + + vector pW = nearPt - pos; scalar normalAlignment = normal & pW/mag(pW); - allWallInteractionSites.append(nearest.rawPoint()); - - if (normalAlignment > 1 - SMALL) + if (normalAlignment > cosPhiMinFlatWall) { - flatWallInteractionSites.append(nearest.rawPoint()); + // Guard against a flat interaction being + // present on the boundary of two or more + // faces, which would create duplicate contact + // points. Duplicates are discarded. + if + ( + !duplicatePointInList + ( + flatSites, + nearPt, + sqr(p.r()*flatWallDuplicateExclusion) + ) + ) + { + flatSites.append(nearPt); + + flatSiteExclusionDistancesSqr.append + ( + sqr(p.r()) - sqr(nearest.distance()) + ); + } + } + else + { + otherSites.append(nearPt); + + otherSiteDistances.append(nearest.distance()); } } } } - Pout<< flatWallInteractionSites << endl; + // All flat interaction sites found, now classify the + // other sites as being in range of a flat interaction, or + // a sharp interaction, being aware of not duplicating the + // sharp interaction sites. - forAll(flatWallInteractionSites, siteI) + // The "other" sites need to evaluated in order of + // ascending distance to their nearest point so that + // grouping occurs around the closest in any group + + labelList sortedOtherSiteIndices; + + sortedOrder(otherSiteDistances, sortedOtherSiteIndices); + + forAll(sortedOtherSiteIndices, siteI) { + label orderedIndex = sortedOtherSiteIndices[siteI]; - scalar nu = this->owner().constProps().poissonsRatio(); + const point& otherPt = otherSites[orderedIndex]; - scalar E = this->owner().constProps().youngsModulus(); + if + ( + !duplicatePointInList + ( + flatSites, + otherPt, + flatSiteExclusionDistancesSqr + ) + ) + { + // Not in range of a flat interaction, must be a + // sharp interaction. - scalar b = 1.5; + if + ( + !duplicatePointInList + ( + sharpSites, + otherPt, + sharpSiteExclusionDistancesSqr + ) + ) + { + sharpSites.append(otherPt); - scalar alpha = 0.52; - - vector r_PW = pt - flatWallInteractionSites[siteI]; - - scalar normalOverlapMag = p.r() - mag(r_PW); - - vector rHat_PW = r_PW/(mag(r_PW) + VSMALL); - - scalar kN = (4.0/3.0)*sqrt(p.r())*E/(2.0*(1.0 - sqr(nu))); - - scalar etaN = alpha*sqrt(p.mass()*kN)*pow025(normalOverlapMag); - - vector fN_PW = - rHat_PW - *(kN*pow(normalOverlapMag, b) - etaN*(p.U() & rHat_PW)); - - p.f() += fN_PW; - - Pout<< "Wall force " << fN_PW << endl; + sharpSiteExclusionDistancesSqr.append + ( + sqr(p.r()) - sqr(otherSiteDistances[orderedIndex]) + ); + } + } } + + evaluateWall(p, flatSites, sharpSites); } } } +template +bool Foam::PairCollision::duplicatePointInList +( + const DynamicList& existingPoints, + const point& pointToTest, + scalar duplicateRangeSqr +) const +{ + forAll(existingPoints, i) + { + if (magSqr(existingPoints[i] - pointToTest) < duplicateRangeSqr) + { + return true; + } + } + + return false; +} + + +template +bool Foam::PairCollision::duplicatePointInList +( + const DynamicList& existingPoints, + const point& pointToTest, + const scalarList& duplicateRangeSqr +) const +{ + forAll(existingPoints, i) + { + if (magSqr(existingPoints[i] - pointToTest) < duplicateRangeSqr[i]) + { + return true; + } + } + + return false; +} + + template void Foam::PairCollision::postInteraction() { @@ -323,6 +455,18 @@ void Foam::PairCollision::evaluatePair } +template +void Foam::PairCollision::evaluateWall +( + typename CloudType::parcelType& p, + const List& flatSites, + const List& sharpSites +) const +{ + wallModel_->evaluateWall(p, flatSites, sharpSites); +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template @@ -342,6 +486,14 @@ Foam::PairCollision::PairCollision this->owner() ) ), + wallModel_ + ( + WallModel::New + ( + this->coeffDict(), + this->owner() + ) + ), il_ ( owner.mesh(), diff --git a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairCollision.H b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairCollision.H index 3ec3ccc25a..d0ad288b21 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairCollision.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairCollision.H @@ -48,6 +48,9 @@ namespace Foam template class PairModel; +template +class WallModel; + /*---------------------------------------------------------------------------*\ Class PairCollision Declaration @@ -58,6 +61,19 @@ class PairCollision : public CollisionModel { + // Static data + + //- Tolerance to determine flat wall interactions + static scalar cosPhiMinFlatWall; + + //- Distance to multiply the distance to a wall with within + // which a duplicate flat wall interaction is defined. If + // cosPhiFlatWall = 1 - e, this = sqrt(2e - e^2) < sqrt(3e) + // for all e < 1, giving a safe tolerance (i.e. no double + // interactions next to each other.) + static scalar flatWallDuplicateExclusion; + + // Private data //- Cell occupancy information for each parcel @@ -66,6 +82,9 @@ class PairCollision //- PairModel to calculate the interaction between two parcels autoPtr > pairModel_; + //- WallModel to calculate the interaction between the parcel and walls + autoPtr > wallModel_; + //- Interactions lists determining which cells are in // interaction range of each other InteractionLists il_; @@ -85,6 +104,20 @@ class PairCollision //- Interactions with walls void wallInteraction(); + bool duplicatePointInList + ( + const DynamicList& existingPoints, + const point& pointToTest, + scalar duplicateRangeSqr + ) const; + + bool duplicatePointInList + ( + const DynamicList& existingPoints, + const point& pointToTest, + const scalarList& duplicateRangeSqr + ) const; + //- Post collision tasks void postInteraction(); @@ -98,6 +131,14 @@ class PairCollision typename CloudType::parcelType& pB ) const; + //- Calculate the wall forces on a parcel + void evaluateWall + ( + typename CloudType::parcelType& p, + const List& flatSites, + const List& sharpSites + ) const; + public: diff --git a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/SpringSliderDashpot/SpringSliderDashpot.C b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/PairSpringSliderDashpot/PairSpringSliderDashpot.C similarity index 93% rename from src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/SpringSliderDashpot/SpringSliderDashpot.C rename to src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/PairSpringSliderDashpot/PairSpringSliderDashpot.C index 710faadd0b..786bffdba4 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/SpringSliderDashpot/SpringSliderDashpot.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/PairSpringSliderDashpot/PairSpringSliderDashpot.C @@ -24,12 +24,12 @@ License \*---------------------------------------------------------------------------*/ -#include "SpringSliderDashpot.H" +#include "PairSpringSliderDashpot.H" // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template -void Foam::SpringSliderDashpot::findMinMaxProperties +void Foam::PairSpringSliderDashpot::findMinMaxProperties ( scalar& RMin, scalar& rhoMax, @@ -45,6 +45,7 @@ void Foam::SpringSliderDashpot::findMinMaxProperties const typename CloudType::parcelType& p = iter(); // Finding minimum diameter to avoid excessive arithmetic + RMin = min(p.d(), RMin); rhoMax = max(p.rho(), rhoMax); @@ -61,9 +62,11 @@ void Foam::SpringSliderDashpot::findMinMaxProperties // then rMin into minimum R, // 1/RMin = 1/rMin + 1/rMin, // RMin = rMin/2 = dMin/4 + RMin /= 4.0; // Multiply by two to create the worst-case relative velocity + UMagMax = 2*UMagMax; } @@ -71,7 +74,7 @@ void Foam::SpringSliderDashpot::findMinMaxProperties // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template -Foam::SpringSliderDashpot::SpringSliderDashpot +Foam::PairSpringSliderDashpot::PairSpringSliderDashpot ( const dictionary& dict, CloudType& cloud @@ -106,21 +109,21 @@ Foam::SpringSliderDashpot::SpringSliderDashpot // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // template -Foam::SpringSliderDashpot::~SpringSliderDashpot() +Foam::PairSpringSliderDashpot::~PairSpringSliderDashpot() {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template -bool Foam::SpringSliderDashpot::controlsTimestep() const +bool Foam::PairSpringSliderDashpot::controlsTimestep() const { return true; } template -Foam::label Foam::SpringSliderDashpot::nSubCycles() const +Foam::label Foam::PairSpringSliderDashpot::nSubCycles() const { if (!(this->owner().size())) { @@ -145,7 +148,7 @@ Foam::label Foam::SpringSliderDashpot::nSubCycles() const template -void Foam::SpringSliderDashpot::evaluatePair +void Foam::PairSpringSliderDashpot::evaluatePair ( typename CloudType::parcelType& pA, typename CloudType::parcelType& pB diff --git a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/SpringSliderDashpot/SpringSliderDashpot.H b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/PairSpringSliderDashpot/PairSpringSliderDashpot.H similarity index 90% rename from src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/SpringSliderDashpot/SpringSliderDashpot.H rename to src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/PairSpringSliderDashpot/PairSpringSliderDashpot.H index e8943e19fd..33ebccc991 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/SpringSliderDashpot/SpringSliderDashpot.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/PairSpringSliderDashpot/PairSpringSliderDashpot.H @@ -23,15 +23,15 @@ License Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Class - Foam::SpringSliderDashpot + Foam::PairSpringSliderDashpot Description Pair forces between particles colliding with a spring, slider, damper model \*---------------------------------------------------------------------------*/ -#ifndef SpringSliderDashpot_H -#define SpringSliderDashpot_H +#ifndef PairSpringSliderDashpot_H +#define PairSpringSliderDashpot_H #include "PairModel.H" #include "CollisionRecord.H" @@ -41,11 +41,11 @@ Description namespace Foam { /*---------------------------------------------------------------------------*\ - Class SpringSliderDashpot Declaration + Class PairSpringSliderDashpot Declaration \*---------------------------------------------------------------------------*/ template -class SpringSliderDashpot +class PairSpringSliderDashpot : public PairModel { @@ -90,17 +90,17 @@ class SpringSliderDashpot public: //- Runtime type information - TypeName("SpringSliderDashpot"); + TypeName("PairSpringSliderDashpot"); // Constructors //- Construct from dictionary - SpringSliderDashpot(const dictionary& dict, CloudType& cloud); + PairSpringSliderDashpot(const dictionary& dict, CloudType& cloud); //- Destructor - virtual ~SpringSliderDashpot(); + virtual ~PairSpringSliderDashpot(); // Member Functions @@ -130,7 +130,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository -# include "SpringSliderDashpot.C" +# include "PairSpringSliderDashpot.C" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallModel/NewWallModel.C b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallModel/NewWallModel.C new file mode 100644 index 0000000000..ba3cf9b54c --- /dev/null +++ b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallModel/NewWallModel.C @@ -0,0 +1,67 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2008-2009 OpenCFD Ltd. + \\/ 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "WallModel.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template +Foam::autoPtr > +Foam::WallModel::New +( + const dictionary& dict, + CloudType& owner +) +{ + word WallModelType(dict.lookup("WallModel")); + + Info<< "Selecting WallModel " << WallModelType + << endl; + + typename dictionaryConstructorTable::iterator cstrIter = + dictionaryConstructorTablePtr_->find(WallModelType); + + if (cstrIter == dictionaryConstructorTablePtr_->end()) + { + FatalErrorIn + ( + "WallModel::New" + "(" + "const dictionary&, " + "CloudType&" + ")" + ) << "Unknown WallModelType type " + << WallModelType + << ", constructor not in hash table" << nl << nl + << " Valid WallModel types are:" << nl + << dictionaryConstructorTablePtr_->sortedToc() << exit(FatalError); + } + + return autoPtr >(cstrIter()(dict, owner)); +} + + +// ************************************************************************* // diff --git a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallModel/WallModel.C b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallModel/WallModel.C new file mode 100644 index 0000000000..788c0ed5a3 --- /dev/null +++ b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallModel/WallModel.C @@ -0,0 +1,81 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2008-2009 OpenCFD Ltd. + \\/ 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "WallModel.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template +Foam::WallModel::WallModel +( + const dictionary& dict, + CloudType& owner, + const word& type +) +: + dict_(dict), + owner_(owner), + coeffDict_(dict.subDict(type + "Coeffs")) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +template +Foam::WallModel::~WallModel() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +const CloudType& +Foam::WallModel::owner() const +{ + return owner_; +} + + +template +const Foam::dictionary& Foam::WallModel::dict() const +{ + return dict_; +} + + +template +const Foam::dictionary& +Foam::WallModel::coeffDict() const +{ + return coeffDict_; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "NewWallModel.C" + +// ************************************************************************* // diff --git a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallModel/WallModel.H b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallModel/WallModel.H new file mode 100644 index 0000000000..a79d4ab9e4 --- /dev/null +++ b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallModel/WallModel.H @@ -0,0 +1,193 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2008-2009 OpenCFD Ltd. + \\/ 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::WallModel + +Description + Templated wall interaction class + +SourceFiles + WallModel.C + NewWallModel.C + +\*---------------------------------------------------------------------------*/ + +#ifndef WallModel_H +#define WallModel_H + +#include "IOdictionary.H" +#include "autoPtr.H" +#include "runTimeSelectionTables.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class WallModel Declaration +\*---------------------------------------------------------------------------*/ + +template +class WallModel +{ + // Private data + + //- The cloud dictionary + const dictionary& dict_; + + //- Reference to the owner cloud class + CloudType& owner_; + + //- The coefficients dictionary + const dictionary coeffDict_; + + +public: + + //- Runtime type information + TypeName("WallModel"); + + //- Declare runtime constructor selection table + declareRunTimeSelectionTable + ( + autoPtr, + WallModel, + dictionary, + ( + const dictionary& dict, + CloudType& owner + ), + (dict, owner) + ); + + + // Constructors + + //- Construct from components + WallModel + ( + const dictionary& dict, + CloudType& owner, + const word& type + ); + + + //- Destructor + virtual ~WallModel(); + + + //- Selector + static autoPtr > New + ( + const dictionary& dict, + CloudType& owner + ); + + + // Access + + //- Return the owner cloud object + const CloudType& owner() const; + + //- Return the dictionary + const dictionary& dict() const; + + //- Return the coefficients dictionary + const dictionary& coeffDict() const; + + + // Member Functions + + //- Whether the WallModel has a timestep limit that will + // require subCycling + virtual bool controlsTimestep() const = 0; + + //- For WallModels that control the timestep, calculate the + // number of subCycles needed to satisfy the minimum + // allowable timestep + virtual label nSubCycles() const = 0; + + //- Calculate the wall interaction between parcels + virtual void evaluateWall + ( + typename CloudType::parcelType& p, + const List& flatSites, + const List& sharpSites + ) const = 0; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#define makeWallModel(CloudType) \ + \ + defineNamedTemplateTypeNameAndDebug(WallModel, 0); \ + \ + defineTemplateRunTimeSelectionTable \ + ( \ + WallModel, \ + dictionary \ + ); + + +#define makeWallModelType(SS, CloudType, ParcelType) \ + \ + defineNamedTemplateTypeNameAndDebug(SS >, 0); \ + \ + WallModel >:: \ + adddictionaryConstructorToTable > > \ + add##SS##CloudType##ParcelType##ConstructorToTable_; + + +#define makeWallModelThermoType(SS, CloudType, ParcelType, ThermoType) \ + \ + defineNamedTemplateTypeNameAndDebug \ + ( \ + SS > >, \ + 0 \ + ); \ + \ + WallModel > >:: \ + adddictionaryConstructorToTable \ + > > > \ + add##SS##CloudType##ParcelType##ThermoType##ConstructorToTable_; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "WallModel.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallSpringSliderDashpot/WallSpringSliderDashpot.C b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallSpringSliderDashpot/WallSpringSliderDashpot.C new file mode 100644 index 0000000000..49d4d13366 --- /dev/null +++ b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallSpringSliderDashpot/WallSpringSliderDashpot.C @@ -0,0 +1,191 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2008-2009 OpenCFD Ltd. + \\/ 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "WallSpringSliderDashpot.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template +void Foam::WallSpringSliderDashpot::findMinMaxProperties +( + scalar& RMin, + scalar& rhoMax, + scalar& UMagMax +) const +{ + RMin = VGREAT; + rhoMax = -VGREAT; + UMagMax = -VGREAT; + + forAllConstIter(typename CloudType, this->owner(), iter) + { + const typename CloudType::parcelType& p = iter(); + + // Finding minimum diameter to avoid excessive arithmetic + RMin = min(p.d(), RMin); + + rhoMax = max(p.rho(), rhoMax); + + UMagMax = max + ( + mag(p.U()) + mag(p.omega())*p.r(), + UMagMax + ); + } + + // Transform the minimum diameter into minimum radius + // rMin = dMin/2 + // then rMin into minimum R, + // 1/RMin = 1/rMin + 1/rMin, + // RMin = rMin/2 = dMin/4 + + RMin /= 4.0; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template +Foam::WallSpringSliderDashpot::WallSpringSliderDashpot +( + const dictionary& dict, + CloudType& cloud +) +: + WallModel(dict, cloud, typeName), + E_(dimensionedScalar(this->coeffDict().lookup("youngsModulus")).value()), + nu_(dimensionedScalar(this->coeffDict().lookup("poissonsRatio")).value()), + alpha_(dimensionedScalar(this->coeffDict().lookup("alpha")).value()), + b_(dimensionedScalar(this->coeffDict().lookup("b")).value()), + mu_(dimensionedScalar(this->coeffDict().lookup("mu")).value()), + collisionResolutionSteps_ + ( + readScalar + ( + this->coeffDict().lookup("collisionResolutionSteps") + ) + ) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +template +Foam::WallSpringSliderDashpot::~WallSpringSliderDashpot() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +bool Foam::WallSpringSliderDashpot::controlsTimestep() const +{ + return true; +} + + +template +Foam::label Foam::WallSpringSliderDashpot::nSubCycles() const +{ + // if (!(this->owner().size())) + // { + // return 1; + // } + + // scalar RMin; + // scalar rhoMax; + // scalar UMagMax; + + // findMinMaxProperties(RMin, rhoMax, UMagMax); + + // // Note: pi^(7/5)*(5/4)^(2/5) = 5.429675 + // scalar minCollisionDeltaT = + // 5.429675 + // *RMin + // *pow(rhoMax/(Estar_*sqrt(UMagMax) + VSMALL), 0.4) + // /collisionResolutionSteps_; + + // return ceil(this->owner().time().deltaT().value()/minCollisionDeltaT); + + return 1; +} + + +template +void Foam::WallSpringSliderDashpot::evaluateWall +( + typename CloudType::parcelType& p, + const List& flatSites, + const List& sharpSites +) const +{ + scalar pNu = this->owner().constProps().poissonsRatio(); + + scalar pE = this->owner().constProps().youngsModulus(); + + scalar Estar = 1/((1 - sqr(pNu))/pE + (1 - sqr(nu_))/E_); + + scalar kN = (4.0/3.0)*sqrt(p.r())*Estar; + + forAll(flatSites, siteI) + { + vector r_PW = p.position() - flatSites[siteI]; + + scalar normalOverlapMag = p.r() - mag(r_PW); + + vector rHat_PW = r_PW/(mag(r_PW) + VSMALL); + + scalar etaN = alpha_*sqrt(p.mass()*kN)*pow025(normalOverlapMag); + + vector fN_PW = + rHat_PW + *(kN*pow(normalOverlapMag, b_) - etaN*(p.U() & rHat_PW)); + + p.f() += fN_PW; + } + + // Treating sharp sites like flat sites + + forAll(sharpSites, siteI) + { + vector r_PW = p.position() - sharpSites[siteI]; + + scalar normalOverlapMag = p.r() - mag(r_PW); + + vector rHat_PW = r_PW/(mag(r_PW) + VSMALL); + + scalar etaN = alpha_*sqrt(p.mass()*kN)*pow025(normalOverlapMag); + + vector fN_PW = + rHat_PW + *(kN*pow(normalOverlapMag, b_) - etaN*(p.U() & rHat_PW)); + + p.f() += fN_PW; + } +} + + +// ************************************************************************* // diff --git a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallSpringSliderDashpot/WallSpringSliderDashpot.H b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallSpringSliderDashpot/WallSpringSliderDashpot.H new file mode 100644 index 0000000000..c1bcf45372 --- /dev/null +++ b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallSpringSliderDashpot/WallSpringSliderDashpot.H @@ -0,0 +1,136 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2008-2009 OpenCFD Ltd. + \\/ 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::WallSpringSliderDashpot + +Description + Forces between particles and walls, interacting with a spring, + slider, damper model + +\*---------------------------------------------------------------------------*/ + +#ifndef WallSpringSliderDashpot_H +#define WallSpringSliderDashpot_H + +#include "WallModel.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +/*---------------------------------------------------------------------------*\ + Class WallSpringSliderDashpot Declaration +\*---------------------------------------------------------------------------*/ + +template +class WallSpringSliderDashpot +: + public WallModel +{ + // Private data + + //- Young's modulus of the wall + scalar E_; + + //- Poisson's ratio of the wall + scalar nu_; + + //- alpha-coefficient, related to coefficient of restitution + scalar alpha_; + + //- Spring power (b = 1 for linear, b = 3/2 for Hertzian) + scalar b_; + + //- Coefficient of friction in for tangential sliding + scalar mu_; + + //- The number of steps over which to resolve the minimum + // harmonic approximation of the collision period + scalar collisionResolutionSteps_; + + + // Private Member Functions + + //- Find the appropriate properties for determining the minimum + //- allowable timestep + void findMinMaxProperties + ( + scalar& RMin, + scalar& rhoMax, + scalar& vMagMax + ) const; + +public: + + //- Runtime type information + TypeName("WallSpringSliderDashpot"); + + + // Constructors + + //- Construct from dictionary + WallSpringSliderDashpot(const dictionary& dict, CloudType& cloud); + + + //- Destructor + virtual ~WallSpringSliderDashpot(); + + + // Member Functions + + //- Whether the WallModel has a timestep limit that will + // require subCycling + virtual bool controlsTimestep() const; + + //- For WallModels that control the timestep, calculate the + // number of subCycles needed to satisfy the minimum + // allowable timestep + virtual label nSubCycles() const; + + //- Calculate the wall interaction between parcels + virtual void evaluateWall + ( + typename CloudType::parcelType& p, + const List& flatSites, + const List& sharpSites + ) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "WallSpringSliderDashpot.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* //