From f4fd4c00dc807947f59c13d3bc55003e01df2f65 Mon Sep 17 00:00:00 2001 From: graham Date: Tue, 25 May 2010 19:46:58 +0100 Subject: [PATCH] ENH: Adding per-patch wall interaction. Rearranged data storage in existing wall model. Improved stability. --- .../WallCollisionRecordI.H | 2 +- .../include/makeParcelCollisionModels.H | 8 + .../makeReactingParcelCollisionModels.H | 10 +- .../PairSpringSliderDashpot.C | 4 +- .../PairSpringSliderDashpot.H | 5 +- .../WallLocalSpringSliderDashpot.C | 354 ++++++++++++++++++ .../WallLocalSpringSliderDashpot.H | 184 +++++++++ .../WallModel/WallModel/WallModel.C | 8 + .../WallModel/WallModel/WallModel.H | 3 + .../WallSpringSliderDashpot.C | 66 ++-- .../WallSpringSliderDashpot.H | 14 +- 11 files changed, 604 insertions(+), 54 deletions(-) create mode 100644 src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallLocalSpringSliderDashpot/WallLocalSpringSliderDashpot.C create mode 100644 src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallLocalSpringSliderDashpot/WallLocalSpringSliderDashpot.H diff --git a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/CollisionRecordList/WallCollisionRecord/WallCollisionRecordI.H b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/CollisionRecordList/WallCollisionRecord/WallCollisionRecordI.H index 1a9a9feb0b..42f5b4f421 100644 --- a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/CollisionRecordList/WallCollisionRecord/WallCollisionRecordI.H +++ b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/CollisionRecordList/WallCollisionRecord/WallCollisionRecordI.H @@ -39,7 +39,7 @@ inline bool Foam::WallCollisionRecord::match // Using the new data as the acceptance criterion scalar cosAcceptanceAngle = magpRel/radius; - if (cosAcceptanceAngle > 1.0) + if (cosAcceptanceAngle > 1.0 + SMALL) { Info<< "pRel_ " << pRel_ << " " << magpRel_ << nl << "pRel " << pRel << " " << magpRel << nl diff --git a/src/lagrangian/intermediate/parcels/include/makeParcelCollisionModels.H b/src/lagrangian/intermediate/parcels/include/makeParcelCollisionModels.H index 98ef4bfbe5..0c84d934bd 100644 --- a/src/lagrangian/intermediate/parcels/include/makeParcelCollisionModels.H +++ b/src/lagrangian/intermediate/parcels/include/makeParcelCollisionModels.H @@ -36,6 +36,7 @@ License #include "PairSpringSliderDashpot.H" #include "WallSpringSliderDashpot.H" +#include "WallLocalSpringSliderDashpot.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -73,6 +74,13 @@ License WallSpringSliderDashpot, \ KinematicCloud, \ ParcelType \ + ); \ + \ + makeWallModelType \ + ( \ + WallLocalSpringSliderDashpot, \ + KinematicCloud, \ + ParcelType \ ); diff --git a/src/lagrangian/intermediate/parcels/include/makeReactingParcelCollisionModels.H b/src/lagrangian/intermediate/parcels/include/makeReactingParcelCollisionModels.H index f1bd4af8a1..289615125f 100644 --- a/src/lagrangian/intermediate/parcels/include/makeReactingParcelCollisionModels.H +++ b/src/lagrangian/intermediate/parcels/include/makeReactingParcelCollisionModels.H @@ -37,6 +37,7 @@ License #include "PairSpringSliderDashpot.H" #include "WallSpringSliderDashpot.H" +#include "WallLocalSpringSliderDashpot.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -99,9 +100,16 @@ License KinematicCloud, \ ParcelType, \ ThermoType \ + ); \ + \ + makeWallModelThermoType \ + ( \ + WallLocalSpringSliderDashpot, \ + KinematicCloud, \ + ParcelType, \ + ThermoType \ ); - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif diff --git a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/PairSpringSliderDashpot/PairSpringSliderDashpot.C b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/PairSpringSliderDashpot/PairSpringSliderDashpot.C index ad3f95ad49..fb732aa19d 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/PairSpringSliderDashpot/PairSpringSliderDashpot.C +++ b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/PairSpringSliderDashpot/PairSpringSliderDashpot.C @@ -100,11 +100,11 @@ Foam::PairSpringSliderDashpot::PairSpringSliderDashpot ) ), volumeFactor_(1.0), - useEquivalentSize_(Switch(this->dict().lookup("useEquivalentSize"))) + useEquivalentSize_(Switch(this->coeffDict().lookup("useEquivalentSize"))) { if (useEquivalentSize_) { - volumeFactor_ = readScalar(this->dict().lookup("volumeFactor")); + volumeFactor_ = readScalar(this->coeffDict().lookup("volumeFactor")); } scalar nu = this->owner().constProps().poissonsRatio(); diff --git a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/PairSpringSliderDashpot/PairSpringSliderDashpot.H b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/PairSpringSliderDashpot/PairSpringSliderDashpot.H index a8982b57eb..9fba1b35e7 100644 --- a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/PairSpringSliderDashpot/PairSpringSliderDashpot.H +++ b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/PairModel/PairSpringSliderDashpot/PairSpringSliderDashpot.H @@ -58,9 +58,6 @@ class PairSpringSliderDashpot // the same Poisson's ratio and Young's modulus scalar Gstar_; - //- Poisson's ratio of both particles - scalar sigma_; - //- alpha-coefficient, related to coefficient of restitution scalar alpha_; @@ -93,7 +90,7 @@ class PairSpringSliderDashpot scalar volumeFactor_; //- Switch to control use of equivalent size particles. Used - // because cbrt calculation is very expensive. + // because the calculation can be very expensive. bool useEquivalentSize_; diff --git a/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallLocalSpringSliderDashpot/WallLocalSpringSliderDashpot.C b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallLocalSpringSliderDashpot/WallLocalSpringSliderDashpot.C new file mode 100644 index 0000000000..996c35801d --- /dev/null +++ b/src/lagrangian/intermediate/submodels/Kinematic/CollisionModel/PairCollision/WallModel/WallLocalSpringSliderDashpot/WallLocalSpringSliderDashpot.C @@ -0,0 +1,354 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2008-2010 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 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 . + +\*---------------------------------------------------------------------------*/ + +#include "WallLocalSpringSliderDashpot.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template +void Foam::WallLocalSpringSliderDashpot::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 + + scalar dEff = p.d(); + + if (useEquivalentSize_) + { + dEff *= cbrt(p.nParticle()*volumeFactor_); + } + + rMin = min(dEff, rMin); + + rhoMax = max(p.rho(), rhoMax); + + UMagMax = max + ( + mag(p.U()) + mag(p.omega())*dEff/2, + UMagMax + ); + } + + // Transform the minimum diameter into minimum radius + // rMin = dMin/2 + + rMin /= 2.0; +} + + +template +void Foam::WallLocalSpringSliderDashpot::evaluateWall +( + typename CloudType::parcelType& p, + const point& site, + const WallSiteData& data, + scalar pREff +) const +{ + // wall patch index + label wPI = patchMap_[data.patchIndex()]; + + // data for this patch + scalar Estar = Estar_[wPI]; + scalar Gstar = Gstar_[wPI]; + scalar alpha = alpha_[wPI]; + scalar b = b_[wPI]; + scalar mu = mu_[wPI]; + + vector r_PW = p.position() - site; + + vector U_PW = p.U() - data.wallData(); + + scalar normalOverlapMag = max(pREff - mag(r_PW), 0.0); + + vector rHat_PW = r_PW/(mag(r_PW) + VSMALL); + + scalar kN = (4.0/3.0)*sqrt(pREff)*Estar; + + scalar etaN = alpha*sqrt(p.mass()*kN)*pow025(normalOverlapMag); + + vector fN_PW = + rHat_PW + *(kN*pow(normalOverlapMag, b) - etaN*(U_PW & rHat_PW)); + + p.f() += fN_PW; + + vector USlip_PW = + U_PW - (U_PW & rHat_PW)*rHat_PW + + (p.omega() ^ (pREff*-rHat_PW)); + + scalar deltaT = this->owner().mesh().time().deltaTValue(); + + vector& tangentialOverlap_PW = + p.collisionRecords().matchWallRecord(-r_PW, pREff).collisionData(); + + tangentialOverlap_PW += USlip_PW*deltaT; + + scalar tangentialOverlapMag = mag(tangentialOverlap_PW); + + if (tangentialOverlapMag > VSMALL) + { + scalar kT = 8.0*sqrt(pREff*normalOverlapMag)*Gstar; + + scalar etaT = etaN; + + // Tangential force + vector fT_PW; + + if (kT*tangentialOverlapMag > mu*mag(fN_PW)) + { + // Tangential force greater than sliding friction, + // particle slips + + fT_PW = -mu*mag(fN_PW)*USlip_PW/mag(USlip_PW); + + tangentialOverlap_PW = vector::zero; + } + else + { + fT_PW = + -kT*tangentialOverlapMag + *tangentialOverlap_PW/tangentialOverlapMag + - etaT*USlip_PW; + } + + p.f() += fT_PW; + + p.torque() += (pREff*-rHat_PW) ^ fT_PW; + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template +Foam::WallLocalSpringSliderDashpot::WallLocalSpringSliderDashpot +( + const dictionary& dict, + CloudType& cloud +) +: + WallModel(dict, cloud, typeName), + Estar_(), + Gstar_(), + alpha_(), + b_(), + mu_(), + patchMap_(), + maxEstarIndex_(-1), + collisionResolutionSteps_ + ( + readScalar + ( + this->coeffDict().lookup("collisionResolutionSteps") + ) + ), + volumeFactor_(1.0), + useEquivalentSize_(Switch(this->coeffDict().lookup("useEquivalentSize"))) +{ + if (useEquivalentSize_) + { + volumeFactor_ = readScalar(this->coeffDict().lookup("volumeFactor")); + } + + scalar pNu = this->owner().constProps().poissonsRatio(); + + scalar pE = this->owner().constProps().youngsModulus(); + + const polyMesh& mesh = cloud.mesh(); + + const polyBoundaryMesh& bMesh = mesh.boundaryMesh(); + + patchMap_.setSize(bMesh.size(), -1); + + DynamicList