33 template<
class CloudType>
45 for (
const typename CloudType::parcelType&
p : this->owner())
51 if (useEquivalentSize_)
53 dEff *=
cbrt(
p.nParticle()*volumeFactor_);
56 rMin =
min(dEff, rMin);
74 template<
class CloudType>
77 typename CloudType::parcelType&
p,
79 const WallSiteData<vector>& data,
85 vector r_PW =
p.position() - site;
87 vector U_PW =
p.U() - data.wallData();
89 scalar r_PW_mag =
mag(r_PW);
91 scalar normalOverlapMag =
max(pREff - r_PW_mag, 0.0);
93 vector rHat_PW = r_PW/(r_PW_mag + VSMALL);
95 scalar etaN = alpha_*
sqrt(
p.mass()*kN)*
pow025(normalOverlapMag);
99 *(kN*
pow(normalOverlapMag, b_) - etaN*(U_PW & rHat_PW));
106 -cohesionEnergyDensity_
114 U_PW - (U_PW & rHat_PW)*rHat_PW
115 + (
p.omega() ^ (pREff*-rHat_PW));
117 scalar deltaT = this->owner().mesh().time().deltaTValue();
119 vector& tangentialOverlap_PW =
120 p.collisionRecords().matchWallRecord(-r_PW, pREff).collisionData();
122 tangentialOverlap_PW += USlip_PW*deltaT;
124 scalar tangentialOverlapMag =
mag(tangentialOverlap_PW);
126 if (tangentialOverlapMag > VSMALL)
128 scalar kT = 8.0*
sqrt(pREff*normalOverlapMag)*Gstar_;
135 if (kT*tangentialOverlapMag > mu_*
mag(fN_PW))
140 fT_PW = -mu_*
mag(fN_PW)*USlip_PW/
mag(USlip_PW);
142 tangentialOverlap_PW =
Zero;
146 fT_PW = - kT*tangentialOverlap_PW - etaT*USlip_PW;
151 p.torque() += (pREff*-rHat_PW) ^ fT_PW;
158 template<
class CloudType>
168 alpha_(this->coeffDict().getScalar(
"alpha")),
169 b_(this->coeffDict().getScalar(
"b")),
170 mu_(this->coeffDict().getScalar(
"mu")),
171 cohesionEnergyDensity_
173 this->coeffDict().getScalar(
"cohesionEnergyDensity")
176 collisionResolutionSteps_
178 this->coeffDict().getScalar(
"collisionResolutionSteps")
181 useEquivalentSize_(
Switch(this->coeffDict().
lookup(
"useEquivalentSize")))
183 if (useEquivalentSize_)
196 Estar_ = 1/((1 -
sqr(pNu))/pE + (1 -
sqr(
nu))/E);
198 Gstar_ = 1/(2*((2 + pNu -
sqr(pNu))/pE + (2 +
nu -
sqr(
nu))/E));
200 cohesion_ = (
mag(cohesionEnergyDensity_) > VSMALL);
206 template<
class CloudType>
213 template<
class CloudType>
219 if (useEquivalentSize_)
221 return p.d()/2*
cbrt(
p.nParticle()*volumeFactor_);
228 template<
class CloudType>
235 template<
class CloudType>
238 if (!(this->owner().size()))
247 findMinMaxProperties(rMin,
rhoMax, UMagMax);
250 scalar minCollisionDeltaT =
254 /collisionResolutionSteps_;
256 return ceil(this->owner().time().deltaTValue()/minCollisionDeltaT);
260 template<
class CloudType>
270 scalar pREff = this->pREff(
p);
272 scalar kN = (4.0/3.0)*
sqrt(pREff)*Estar_;
274 forAll(flatSitePoints, siteI)
279 flatSitePoints[siteI],
287 forAll(sharpSitePoints, siteI)
294 sharpSitePoints[siteI],
295 sharpSiteData[siteI],
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
A list of keyword definitions, which are a keyword followed by a number of values (eg...
const dictionary & coeffDict() const
Return the coefficients dictionary.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
const CloudType & owner() const
Return the owner cloud object.
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensionedScalar pow025(const dimensionedScalar &ds)
A simple wrapper around bool so that it can be read as a word: true/false, on/off, yes/no, any/none. Also accepts 0/1 as a string and shortcuts t/f, y/n.
Forces between particles and walls, interacting with a spring, slider, damper model.
virtual label nSubCycles() const
For WallModels that control the timestep, calculate the.
Lookup type of boundary radiation properties.
virtual ~WallSpringSliderDashpot()
Destructor.
#define forAll(list, i)
Loop across all elements in list.
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, IOobjectOption::readOption readOpt=IOobjectOption::MUST_READ) const
Find entry and assign to T val. FatalIOError if it is found and the number of tokens is incorrect...
A cloud is a registry collection of lagrangian particles.
dimensionedScalar cbrt(const dimensionedScalar &ds)
constexpr scalar pi(M_PI)
scalar getScalar(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Same as get< scalar >(const word&, keyType::option)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Templated wall interaction class.
Stores the patch ID and templated data to represent a collision with a wall to be passed to the wall ...
ParcelType parcelType
Type of parcel the cloud was instantiated for.
WallSpringSliderDashpot(const dictionary &dict, CloudType &cloud)
Construct from dictionary.
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
vector point
Point is a vector.
Templated base class for dsmc cloud.
const List< typename ParcelType::constantProperties > & constProps() const
Return all of the constant properties.
virtual scalar pREff(const typename CloudType::parcelType &p) const
Return the effective radius for a particle for the model.
virtual bool controlsTimestep() const
Whether the WallModel has a timestep limit that will.
const dimensionedScalar rhoMax
static constexpr const zero Zero
Global zero (0)