30 template<
class CloudType>
50 if (useEquivalentSize_)
52 dEff *=
cbrt(
p.nParticle()*volumeFactor_);
55 RMin =
min(dEff, RMin);
82 template<
class CloudType>
95 cohesionEnergyDensity_
100 collisionResolutionSteps_
105 useEquivalentSize_(
Switch(this->coeffDict().
lookup(
"useEquivalentSize")))
107 if (useEquivalentSize_)
112 scalar
nu = this->owner().constProps().poissonsRatio();
114 scalar E = this->owner().constProps().youngsModulus();
116 Estar_ = E/(2.0*(1.0 -
sqr(
nu)));
118 scalar
G = E/(2.0*(1.0 +
nu));
120 Gstar_ =
G/(2.0*(2.0 -
nu));
122 cohesion_ = (
mag(cohesionEnergyDensity_) > VSMALL);
128 template<
class CloudType>
135 template<
class CloudType>
142 template<
class CloudType>
145 if (!(this->owner().size()))
154 findMinMaxProperties(RMin,
rhoMax, UMagMax);
157 scalar minCollisionDeltaT =
161 /collisionResolutionSteps_;
163 return ceil(this->owner().time().deltaTValue()/minCollisionDeltaT);
167 template<
class CloudType>
174 vector r_AB = (pA.position() - pB.position());
176 scalar dAEff = pA.d();
178 if (useEquivalentSize_)
180 dAEff *=
cbrt(pA.nParticle()*volumeFactor_);
183 scalar dBEff = pB.d();
185 if (useEquivalentSize_)
187 dBEff *=
cbrt(pB.nParticle()*volumeFactor_);
190 scalar r_AB_mag =
mag(r_AB);
192 scalar normalOverlapMag = 0.5*(dAEff + dBEff) - r_AB_mag;
194 if (normalOverlapMag > 0)
198 vector rHat_AB = r_AB/(r_AB_mag + VSMALL);
200 vector U_AB = pA.U() - pB.U();
203 scalar
R = 0.5*dAEff*dBEff/(dAEff + dBEff);
206 scalar
M = pA.mass()*pB.mass()/(pA.mass() + pB.mass());
208 scalar kN = (4.0/3.0)*
sqrt(
R)*Estar_;
210 scalar etaN = alpha_*
sqrt(
M*kN)*
pow025(normalOverlapMag);
215 *(kN*
pow(normalOverlapMag, b_) - etaN*(U_AB & rHat_AB));
222 -cohesionEnergyDensity_
223 *overlapArea(dAEff/2.0, dBEff/2.0, r_AB_mag)
231 U_AB - (U_AB & rHat_AB)*rHat_AB
232 + (pA.omega() ^ (dAEff/2*-rHat_AB))
233 - (pB.omega() ^ (dBEff/2*rHat_AB));
235 scalar deltaT = this->owner().mesh().time().deltaTValue();
237 vector& tangentialOverlap_AB =
238 pA.collisionRecords().matchPairRecord
244 vector& tangentialOverlap_BA =
245 pB.collisionRecords().matchPairRecord
251 vector deltaTangentialOverlap_AB = USlip_AB*deltaT;
253 tangentialOverlap_AB += deltaTangentialOverlap_AB;
254 tangentialOverlap_BA += -deltaTangentialOverlap_AB;
256 scalar tangentialOverlapMag =
mag(tangentialOverlap_AB);
258 if (tangentialOverlapMag > VSMALL)
260 scalar kT = 8.0*
sqrt(
R*normalOverlapMag)*Gstar_;
267 if (kT*tangentialOverlapMag > mu_*
mag(fN_AB))
272 fT_AB = -mu_*
mag(fN_AB)*USlip_AB/
mag(USlip_AB);
274 tangentialOverlap_AB = vector::zero;
275 tangentialOverlap_BA = vector::zero;
280 -kT*tangentialOverlapMag
281 *tangentialOverlap_AB/tangentialOverlapMag
288 pA.torque() += (dAEff/2*-rHat_AB) ^ fT_AB;
289 pB.torque() += (dBEff/2*rHat_AB) ^ -fT_AB;