mirror of
https://github.com/PhasicFlow/phasicFlow.git
synced 2025-07-28 03:27:05 +00:00
This is the first merge from main into MPI branch
Merge branch 'main' into local-MPI
This commit is contained in:
@ -21,6 +21,12 @@ interaction/interaction.cpp
|
||||
sphereInteraction/sphereInteractionsLinearModels.cpp
|
||||
sphereInteraction/sphereInteractionsNonLinearModels.cpp
|
||||
sphereInteraction/sphereInteractionsNonLinearModModels.cpp
|
||||
|
||||
grainInteraction/grainInteractionsLinearModels.cpp
|
||||
grainInteraction/grainInteractionsNonLinearModels.cpp
|
||||
grainInteraction/grainInteractionsNonLinearModModels.cpp
|
||||
|
||||
|
||||
)
|
||||
|
||||
if(pFlow_Build_MPI)
|
||||
|
339
src/Interaction/Models/contactForce/cGAbsoluteLinearCF.hpp
Executable file
339
src/Interaction/Models/contactForce/cGAbsoluteLinearCF.hpp
Executable file
@ -0,0 +1,339 @@
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __cGAbsoluteLinearCF_hpp__
|
||||
#define __cGAbsoluteLinearCF_hpp__
|
||||
|
||||
#include "types.hpp"
|
||||
#include "symArrays.hpp"
|
||||
|
||||
|
||||
namespace pFlow::cfModels
|
||||
{
|
||||
|
||||
template<bool limited=true>
|
||||
class cGAbsoluteLinear
|
||||
{
|
||||
public:
|
||||
|
||||
struct contactForceStorage
|
||||
{
|
||||
realx3 overlap_t_ = 0.0;
|
||||
};
|
||||
|
||||
|
||||
struct linearProperties
|
||||
{
|
||||
real kn_ = 1000.0;
|
||||
real kt_ = 800.0;
|
||||
real en_ = 0.0;
|
||||
real ethat_ = 0.0;
|
||||
real mu_ = 0.00001;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
linearProperties(){}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
linearProperties(real kn, real kt, real en, real etha_t, real mu ):
|
||||
kn_(kn), kt_(kt), en_(en),ethat_(etha_t), mu_(mu)
|
||||
{}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
linearProperties(const linearProperties&)=default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
linearProperties& operator=(const linearProperties&)=default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
~linearProperties() = default;
|
||||
};
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
using LinearArrayType = symArray<linearProperties>;
|
||||
|
||||
int32 numMaterial_ = 0;
|
||||
|
||||
ViewType1D<real> rho_;
|
||||
|
||||
LinearArrayType linearProperties_;
|
||||
|
||||
int32 addDissipationModel_;
|
||||
|
||||
|
||||
bool readLinearDictionary(const dictionary& dict)
|
||||
{
|
||||
|
||||
|
||||
auto kn = dict.getVal<realVector>("kn");
|
||||
auto kt = dict.getVal<realVector>("kt");
|
||||
auto en = dict.getVal<realVector>("en");
|
||||
auto et = dict.getVal<realVector>("et");
|
||||
auto mu = dict.getVal<realVector>("mu");
|
||||
|
||||
auto nElem = kn.size();
|
||||
|
||||
if(nElem != kt.size())
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"sizes of kn("<<nElem<<") and kt("<<kt.size()<<") do not match.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(nElem != kt.size())
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"sizes of kn("<<nElem<<") and kt("<<kt.size()<<") do not match.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(nElem != en.size())
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"sizes of kn("<<nElem<<") and en("<<en.size()<<") do not match.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(nElem != et.size())
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"sizes of kn("<<nElem<<") and et("<<et.size()<<") do not match.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(nElem != mu.size())
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"sizes of kn("<<nElem<<") and mu("<<mu.size()<<") do not match.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// check if size of vector matchs a symetric array
|
||||
uint32 nMat;
|
||||
if( !LinearArrayType::getN(nElem, nMat) )
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"sizes of properties do not match a symetric array with size ("<<
|
||||
numMaterial_<<"x"<<numMaterial_<<").\n";
|
||||
return false;
|
||||
}
|
||||
else if( numMaterial_ != nMat)
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"size mismatch for porperties. \n"<<
|
||||
"you supplied "<< numMaterial_<<" items in materials list and "<<
|
||||
nMat << " for other properties.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
realVector etha_t("etha_t", nElem);
|
||||
|
||||
ForAll(i , kn)
|
||||
{
|
||||
|
||||
etha_t[i] = -2.0*log( et[i])*sqrt(kt[i]*2/7) /
|
||||
sqrt(log(pow(et[i],2))+ pow(Pi,2));
|
||||
}
|
||||
|
||||
Vector<linearProperties> prop("prop", nElem);
|
||||
ForAll(i,kn)
|
||||
{
|
||||
prop[i] = {kn[i], kt[i], en[i], etha_t[i], mu[i] };
|
||||
}
|
||||
|
||||
linearProperties_.assign(prop);
|
||||
|
||||
auto adm = dict.getVal<word>("additionalDissipationModel");
|
||||
|
||||
|
||||
if(adm == "none")
|
||||
{
|
||||
addDissipationModel_ = 1;
|
||||
}
|
||||
else if(adm == "LU")
|
||||
{
|
||||
addDissipationModel_ = 2;
|
||||
}
|
||||
else if (adm == "GB")
|
||||
{
|
||||
addDissipationModel_ = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
addDissipationModel_ = 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
static const char* modelName()
|
||||
{
|
||||
if constexpr (limited)
|
||||
{
|
||||
return "cGAbsoluteLinearLimited";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "cGAbsoluteLinearNonLimited";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
|
||||
TypeInfoNV(modelName());
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
cGAbsoluteLinear(){}
|
||||
|
||||
cGAbsoluteLinear(int32 nMaterial, const ViewType1D<real>& rho, const dictionary& dict)
|
||||
:
|
||||
numMaterial_(nMaterial),
|
||||
rho_("rho",nMaterial),
|
||||
linearProperties_("linearProperties",nMaterial)
|
||||
{
|
||||
|
||||
Kokkos::deep_copy(rho_,rho);
|
||||
if(!readLinearDictionary(dict))
|
||||
{
|
||||
fatalExit;
|
||||
}
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
cGAbsoluteLinear(const cGAbsoluteLinear&) = default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
cGAbsoluteLinear(cGAbsoluteLinear&&) = default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
cGAbsoluteLinear& operator=(const cGAbsoluteLinear&) = default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
cGAbsoluteLinear& operator=(cGAbsoluteLinear&&) = default;
|
||||
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
~cGAbsoluteLinear()=default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
int32 numMaterial()const
|
||||
{
|
||||
return numMaterial_;
|
||||
}
|
||||
|
||||
//// - Methods
|
||||
INLINE_FUNCTION_HD
|
||||
void contactForce
|
||||
(
|
||||
const real dt,
|
||||
const uint32 i,
|
||||
const uint32 j,
|
||||
const uint32 propId_i,
|
||||
const uint32 propId_j,
|
||||
const real Ri,
|
||||
const real Rj,
|
||||
const real cGFi,
|
||||
const real cGFj,
|
||||
const real ovrlp_n,
|
||||
const realx3& Vr,
|
||||
const realx3& Nij,
|
||||
contactForceStorage& history,
|
||||
realx3& FCn,
|
||||
realx3& FCt
|
||||
)const
|
||||
{
|
||||
|
||||
|
||||
auto prop = linearProperties_(propId_i,propId_j);
|
||||
|
||||
|
||||
real f_ = ( cGFi + cGFj )/2 ;
|
||||
|
||||
|
||||
real vrn = dot(Vr, Nij);
|
||||
realx3 Vt = Vr - vrn*Nij;
|
||||
|
||||
history.overlap_t_ += Vt*dt;
|
||||
|
||||
real mi = 3*Pi/4*pow(Ri,3)*rho_[propId_i];
|
||||
real mj = 3*Pi/4*pow(Rj,3)*rho_[propId_j];
|
||||
|
||||
real sqrt_meff = sqrt((mi*mj)/(mi+mj));
|
||||
|
||||
|
||||
// disipation model
|
||||
if (addDissipationModel_==2)
|
||||
{
|
||||
prop.en_ = sqrt(1+((pow(prop.en_,2)-1)*f_));
|
||||
}
|
||||
else if (addDissipationModel_==3)
|
||||
{
|
||||
auto pie =3.14;
|
||||
prop.en_ = exp((pow(f_,static_cast<real>(1.5))*log(prop.en_)*sqrt( (1-((pow(log(prop.en_),2))/(pow(log(prop.en_),2)+pow(pie,2))))/(1-(pow(f_,3)*(pow(log(prop.en_),2))/(pow(log(prop.en_),2)+pow(pie,2)))) ) ));
|
||||
}
|
||||
|
||||
real ethan_ = -2.0*log(prop.en_)*sqrt(prop.kn_)/
|
||||
sqrt(pow(log(prop.en_),2)+ pow(Pi,2));
|
||||
|
||||
//REPORT(0)<<"\n en n is : "<<END_REPORT;
|
||||
//REPORT(0)<< prop.en_ <<END_REPORT;
|
||||
|
||||
FCn = ( -pow(f_,3)*prop.kn_ * ovrlp_n - sqrt_meff * pow(f_,static_cast<real>(1.5)) * ethan_ * vrn)*Nij;
|
||||
FCt = ( -pow(f_,3)*prop.kt_ * history.overlap_t_ - sqrt_meff * pow(f_,static_cast<real>(1.5)) * prop.ethat_*Vt);
|
||||
|
||||
real ft = length(FCt);
|
||||
real ft_fric = prop.mu_ * length(FCn);
|
||||
|
||||
if(ft > ft_fric)
|
||||
{
|
||||
if( length(history.overlap_t_) >zero)
|
||||
{
|
||||
if constexpr (limited)
|
||||
{
|
||||
FCt *= (ft_fric/ft);
|
||||
history.overlap_t_ = - (FCt/prop.kt_);
|
||||
}
|
||||
else
|
||||
{
|
||||
FCt = (FCt/ft)*ft_fric;
|
||||
}
|
||||
//cout<<"friction is applied here \n";
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
FCt = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} //pFlow::cfModels
|
||||
|
||||
#endif
|
307
src/Interaction/Models/contactForce/cGNonLinearCF.hpp
Normal file
307
src/Interaction/Models/contactForce/cGNonLinearCF.hpp
Normal file
@ -0,0 +1,307 @@
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __cGNonLinearCF_hpp__
|
||||
#define __cGNonLinearCF_hpp__
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
namespace pFlow::cfModels
|
||||
{
|
||||
|
||||
template<bool limited=true>
|
||||
class cGNonLinear
|
||||
{
|
||||
public:
|
||||
|
||||
struct contactForceStorage
|
||||
{
|
||||
realx3 overlap_t_ = 0.0;
|
||||
};
|
||||
|
||||
struct cGNonLinearProperties
|
||||
{
|
||||
real Yeff_ = 1000000.0;
|
||||
real Geff_ = 8000000.0;
|
||||
real en_ = 1.0;
|
||||
real mu_ = 0.00001;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
cGNonLinearProperties(){}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
cGNonLinearProperties(real Yeff, real Geff, real en, real mu ):
|
||||
Yeff_(Yeff), Geff_(Geff), en_(en), mu_(mu)
|
||||
{}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
cGNonLinearProperties(const cGNonLinearProperties&)=default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
cGNonLinearProperties& operator=(const cGNonLinearProperties&)=default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
~cGNonLinearProperties() = default;
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
using cGNonLinearArrayType = symArray<cGNonLinearProperties>;
|
||||
|
||||
int32 numMaterial_ = 0;
|
||||
|
||||
ViewType1D<real> rho_;
|
||||
|
||||
int32 addDissipationModel_;
|
||||
|
||||
cGNonLinearArrayType nonlinearProperties_;
|
||||
|
||||
bool readNonLinearDictionary(const dictionary& dict)
|
||||
{
|
||||
auto Yeff = dict.getVal<realVector>("Yeff");
|
||||
auto Geff = dict.getVal<realVector>("Geff");
|
||||
auto nu = dict.getVal<realVector>("nu");
|
||||
auto en = dict.getVal<realVector>("en");
|
||||
auto mu = dict.getVal<realVector>("mu");
|
||||
|
||||
auto nElem = Yeff.size();
|
||||
|
||||
if(nElem != nu.size())
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"sizes of Yeff("<<nElem<<") and nu("<<nu.size()<<") do not match.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(nElem != en.size())
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"sizes of Yeff("<<nElem<<") and en("<<en.size()<<") do not match.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if(nElem != mu.size())
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"sizes of Yeff("<<nElem<<") and mu("<<mu.size()<<") do not match.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// check if size of vector matchs a symetric array
|
||||
uint32 nMat;
|
||||
if( !cGNonLinearArrayType::getN(nElem, nMat) )
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"sizes of properties do not match a symetric array with size ("<<
|
||||
numMaterial_<<"x"<<numMaterial_<<").\n";
|
||||
return false;
|
||||
}
|
||||
else if( numMaterial_ != nMat)
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"size mismatch for porperties. \n";
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector<cGNonLinearProperties> prop("prop",nElem);
|
||||
ForAll(i,Yeff)
|
||||
{
|
||||
prop[i] = {Yeff[i], Geff[i], en[i], mu[i]};
|
||||
}
|
||||
|
||||
nonlinearProperties_.assign(prop);
|
||||
|
||||
auto adm = dict.getVal<word>("additionalDissipationModel");
|
||||
if(adm == "none")
|
||||
{
|
||||
addDissipationModel_ = 1;
|
||||
}
|
||||
else if(adm == "LU")
|
||||
{
|
||||
addDissipationModel_ = 2;
|
||||
}
|
||||
else if (adm == "GB")
|
||||
{
|
||||
addDissipationModel_ = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
addDissipationModel_ = 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
static const char* modelName()
|
||||
{
|
||||
if constexpr (limited)
|
||||
{
|
||||
return "cGNonLinearLimited";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "cGNonLinearNonLimited";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
TypeInfoNV(modelName());
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
cGNonLinear(){}
|
||||
|
||||
cGNonLinear(
|
||||
int32 nMaterial,
|
||||
const ViewType1D<real>& rho,
|
||||
const dictionary& dict)
|
||||
:
|
||||
numMaterial_(nMaterial),
|
||||
rho_("rho",nMaterial),
|
||||
nonlinearProperties_("cGNonLinearProperties",nMaterial)
|
||||
{
|
||||
|
||||
Kokkos::deep_copy(rho_,rho);
|
||||
if(!readNonLinearDictionary(dict))
|
||||
{
|
||||
fatalExit;
|
||||
}
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
cGNonLinear(const cGNonLinear&) = default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
cGNonLinear(cGNonLinear&&) = default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
cGNonLinear& operator=(const cGNonLinear&) = default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
cGNonLinear& operator=(cGNonLinear&&) = default;
|
||||
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
~cGNonLinear()=default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
int32 numMaterial()const
|
||||
{
|
||||
return numMaterial_;
|
||||
}
|
||||
|
||||
//// - Methods
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
void contactForce
|
||||
(
|
||||
const real dt,
|
||||
const uint32 i,
|
||||
const uint32 j,
|
||||
const uint32 propId_i,
|
||||
const uint32 propId_j,
|
||||
const real Ri,
|
||||
const real Rj,
|
||||
const real cGFi,
|
||||
const real cGFj,
|
||||
const real ovrlp_n,
|
||||
const realx3& Vr,
|
||||
const realx3& Nij,
|
||||
contactForceStorage& history,
|
||||
realx3& FCn,
|
||||
realx3& FCt
|
||||
)const
|
||||
{
|
||||
|
||||
const auto prop = nonlinearProperties_(propId_i,propId_j);
|
||||
|
||||
const real f = 2/( 1/cGFi + 1/cGFj );
|
||||
|
||||
real vrn = dot(Vr, Nij);
|
||||
realx3 Vt = Vr - vrn*Nij;
|
||||
|
||||
history.overlap_t_ += Vt*dt;
|
||||
|
||||
real mi = 3*Pi/4*pow(Ri,static_cast<real>(3))*rho_[propId_i];
|
||||
real mj = 3*Pi/4*pow(Rj,static_cast<real>(3))*rho_[propId_j];
|
||||
real Reff = 1/(1/Ri + 1/Rj);
|
||||
|
||||
real K_hertz = 4.0/3.0*prop.Yeff_*sqrt(Reff);
|
||||
real sqrt_meff_K_hertz = sqrt((mi*mj)/(mi+mj) * K_hertz);
|
||||
|
||||
real en = prop.en_;
|
||||
if (addDissipationModel_==2)
|
||||
{
|
||||
en = sqrt(1+((pow(prop.en_,2)-1)*f));
|
||||
}
|
||||
else if (addDissipationModel_==3)
|
||||
{
|
||||
|
||||
en = exp((pow(f,static_cast<real>(1.5))*log(prop.en_)*sqrt( (1-((pow(log(prop.en_),2))/(pow(log(prop.en_),2)+pow(Pi,2))))/(1-(pow(f,3)*(pow(log(prop.en_),2))/(pow(log(prop.en_),2)+pow(Pi,2)))) ) ));
|
||||
}
|
||||
|
||||
real Kn = static_cast<real>(4.0/3.0) * prop.Yeff_ * sqrt(Reff*ovrlp_n);
|
||||
|
||||
real ethan_ = -2.0*log(en)*sqrt(Kn)/
|
||||
sqrt(pow(log(en),2)+ pow(Pi,2));
|
||||
|
||||
FCn = ( - Kn*ovrlp_n -
|
||||
sqrt_meff_K_hertz*ethan_*pow(ovrlp_n,static_cast<real>(0.25))*vrn)*Nij;
|
||||
|
||||
FCt = (f*f)*(- static_cast<real>(8.0) * prop.Geff_ * sqrt(Reff*ovrlp_n) ) * history.overlap_t_;
|
||||
|
||||
real ft = length(FCt);
|
||||
real ft_fric = prop.mu_ * length(FCn);
|
||||
|
||||
// apply friction
|
||||
if(ft > ft_fric)
|
||||
{
|
||||
if( length(history.overlap_t_) >0.0)
|
||||
{
|
||||
if constexpr (limited)
|
||||
{
|
||||
real kt = static_cast<real>(8.0) * prop.Geff_ * sqrt(Reff*ovrlp_n);
|
||||
FCt *= (ft_fric/ft);
|
||||
history.overlap_t_ = - FCt/(f*f*kt);
|
||||
}
|
||||
else
|
||||
{
|
||||
FCt = (FCt/ft)*ft_fric;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
FCt = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
} //pFlow::CFModels
|
||||
|
||||
#endif
|
326
src/Interaction/Models/contactForce/cGRelativeLinearCF.hpp
Executable file
326
src/Interaction/Models/contactForce/cGRelativeLinearCF.hpp
Executable file
@ -0,0 +1,326 @@
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __cGRelativeLinearCF_hpp__
|
||||
#define __cGRelativeLinearCF_hpp__
|
||||
|
||||
#include "types.hpp"
|
||||
#include "symArrays.hpp"
|
||||
|
||||
|
||||
|
||||
namespace pFlow::cfModels
|
||||
{
|
||||
|
||||
template<bool limited=true>
|
||||
class cGRelativeLinear
|
||||
{
|
||||
public:
|
||||
|
||||
struct contactForceStorage
|
||||
{
|
||||
realx3 overlap_t_ = 0.0;
|
||||
};
|
||||
|
||||
|
||||
struct linearProperties
|
||||
{
|
||||
real kn_ = 1000.0;
|
||||
real kt_ = 800.0;
|
||||
real en_ = 1.0;
|
||||
real mu_ = 0.00001;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
linearProperties(){}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
linearProperties(real kn, real kt, real en, real mu ):
|
||||
kn_(kn), kt_(kt), en_(en), mu_(mu)
|
||||
{}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
linearProperties(const linearProperties&)=default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
linearProperties& operator=(const linearProperties&)=default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
~linearProperties() = default;
|
||||
};
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
using LinearArrayType = symArray<linearProperties>;
|
||||
|
||||
int32 numMaterial_ = 0;
|
||||
|
||||
ViewType1D<real> rho_;
|
||||
|
||||
LinearArrayType linearProperties_;
|
||||
|
||||
int32 addDissipationModel_;
|
||||
|
||||
|
||||
bool readLinearDictionary(const dictionary& dict)
|
||||
{
|
||||
|
||||
|
||||
auto kn = dict.getVal<realVector>("kn");
|
||||
auto kt = dict.getVal<realVector>("kt");
|
||||
auto en = dict.getVal<realVector>("en");
|
||||
auto mu = dict.getVal<realVector>("mu");
|
||||
|
||||
|
||||
auto nElem = kn.size();
|
||||
|
||||
|
||||
if(nElem != kt.size())
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"sizes of kn("<<nElem<<") and kt("<<kt.size()<<") do not match.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(nElem != en.size())
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"sizes of kn("<<nElem<<") and en("<<en.size()<<") do not match.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if(nElem != mu.size())
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"sizes of kn("<<nElem<<") and mu("<<mu.size()<<") do not match.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// check if size of vector matchs a symetric array
|
||||
uint32 nMat;
|
||||
if( !LinearArrayType::getN(nElem, nMat) )
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"sizes of properties do not match a symetric array with size ("<<
|
||||
numMaterial_<<"x"<<numMaterial_<<").\n";
|
||||
return false;
|
||||
}
|
||||
else if( numMaterial_ != nMat)
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"size mismatch for porperties. \n"<<
|
||||
"you supplied "<< numMaterial_<<" items in materials list and "<<
|
||||
nMat << " for other properties.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Vector<linearProperties> prop("prop", nElem);
|
||||
ForAll(i,kn)
|
||||
{
|
||||
prop[i] = {kn[i], kt[i], en[i], mu[i] };
|
||||
}
|
||||
|
||||
linearProperties_.assign(prop);
|
||||
|
||||
|
||||
auto adm = dict.getVal<word>("additionalDissipationModel");
|
||||
if(adm == "none")
|
||||
{
|
||||
addDissipationModel_ = 1;
|
||||
}
|
||||
else if(adm == "LU")
|
||||
{
|
||||
addDissipationModel_ = 2;
|
||||
}
|
||||
else if (adm == "GB")
|
||||
{
|
||||
addDissipationModel_ = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
addDissipationModel_ = 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
static const char* modelName()
|
||||
{
|
||||
if constexpr (limited)
|
||||
{
|
||||
return "cGRelativeLinearLimited";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "cGRelativeLinearNonLimited";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
|
||||
TypeInfoNV(modelName());
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
cGRelativeLinear(){}
|
||||
|
||||
cGRelativeLinear(int32 nMaterial, const ViewType1D<real>& rho, const dictionary& dict)
|
||||
:
|
||||
numMaterial_(nMaterial),
|
||||
rho_("rho",nMaterial),
|
||||
linearProperties_("linearProperties",nMaterial)
|
||||
{
|
||||
|
||||
Kokkos::deep_copy(rho_,rho);
|
||||
if(!readLinearDictionary(dict))
|
||||
{
|
||||
fatalExit;
|
||||
}
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
cGRelativeLinear(const cGRelativeLinear&) = default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
cGRelativeLinear(cGRelativeLinear&&) = default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
cGRelativeLinear& operator=(const cGRelativeLinear&) = default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
cGRelativeLinear& operator=(cGRelativeLinear&&) = default;
|
||||
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
~cGRelativeLinear()=default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
int32 numMaterial()const
|
||||
{
|
||||
return numMaterial_;
|
||||
}
|
||||
|
||||
//// - Methods
|
||||
INLINE_FUNCTION_HD
|
||||
void contactForce
|
||||
(
|
||||
const real dt,
|
||||
const uint32 i,
|
||||
const uint32 j,
|
||||
const uint32 propId_i,
|
||||
const uint32 propId_j,
|
||||
const real Ri,
|
||||
const real Rj,
|
||||
const real cGFi,
|
||||
const real cGFj,
|
||||
const real ovrlp_n,
|
||||
const realx3& Vr,
|
||||
const realx3& Nij,
|
||||
contactForceStorage& history,
|
||||
realx3& FCn,
|
||||
realx3& FCt
|
||||
)const
|
||||
{
|
||||
|
||||
auto prop = linearProperties_(propId_i,propId_j);
|
||||
|
||||
real f_ = ( cGFi + cGFj )/2 ;
|
||||
|
||||
|
||||
real vrn = dot(Vr, Nij);
|
||||
realx3 Vt = Vr - vrn*Nij;
|
||||
|
||||
history.overlap_t_ += Vt*dt;
|
||||
|
||||
real mi = 3*Pi/4*pow(Ri,3)*rho_[propId_i];
|
||||
real mj = 3*Pi/4*pow(Rj,3)*rho_[propId_j];
|
||||
|
||||
real sqrt_meff = sqrt((mi*mj)/(mi+mj));
|
||||
|
||||
real en = prop.en_;
|
||||
if (addDissipationModel_==2)
|
||||
{
|
||||
en = sqrt(1+((pow(prop.en_,2)-1)*f_));
|
||||
}
|
||||
else if (addDissipationModel_==3)
|
||||
{
|
||||
|
||||
en = exp(
|
||||
(
|
||||
pow(f_,static_cast<real>(1.5))*
|
||||
log(prop.en_)*
|
||||
sqrt(
|
||||
(1-((pow(log(prop.en_),static_cast<real>(2.0))
|
||||
)/
|
||||
(
|
||||
pow(log(prop.en_),static_cast<real>(2.0))+
|
||||
pow(Pi,static_cast<real>(2.0)))))/
|
||||
(1-(pow(f_,3)*(pow(log(prop.en_),2))/
|
||||
(pow(log(prop.en_),static_cast<real>(2.0))+
|
||||
pow(Pi,static_cast<real>(2.0))))) ) ));
|
||||
}
|
||||
|
||||
real ethan_ = -2.0*log(en)*sqrt(prop.kn_)/
|
||||
sqrt(pow(log(en),2)+ pow(Pi,2));
|
||||
|
||||
|
||||
FCn = ( -f_*prop.kn_ * ovrlp_n - sqrt_meff * pow(f_,half) * ethan_ * vrn)*Nij;
|
||||
FCt = ( -f_*prop.kt_ * history.overlap_t_);
|
||||
|
||||
|
||||
|
||||
real ft = length(FCt);
|
||||
real ft_fric = prop.mu_ * length(FCn);
|
||||
|
||||
if(ft > ft_fric)
|
||||
{
|
||||
if( length(history.overlap_t_) >static_cast<real>(0.0))
|
||||
{
|
||||
if constexpr (limited)
|
||||
{
|
||||
FCt *= (ft_fric/ft);
|
||||
history.overlap_t_ = - (FCt/prop.kt_);
|
||||
}
|
||||
else
|
||||
{
|
||||
FCt = (FCt/ft)*ft_fric;
|
||||
}
|
||||
//cout<<"friction is applied here \n";
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
FCt = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} //pFlow::cfModels
|
||||
|
||||
#endif
|
@ -139,10 +139,10 @@ protected:
|
||||
ForAll(i , kn)
|
||||
{
|
||||
etha_n[i] = -2.0*log(en[i])*sqrt(kn[i])/
|
||||
sqrt(pow(log(en[i]),2.0)+ pow(Pi,2.0));
|
||||
sqrt(pow(log(en[i]),static_cast<real>(2.0))+ pow(Pi,static_cast<real>(2.0)));
|
||||
|
||||
etha_t[i] = -2.0*log( et[i]*sqrt(kt[i]) )/
|
||||
sqrt(pow(log(et[i]),2.0)+ pow(Pi,2.0));
|
||||
sqrt(pow(log(et[i]),static_cast<real>(2.0))+ pow(Pi,static_cast<real>(2.0)));
|
||||
}
|
||||
|
||||
Vector<linearProperties> prop("prop", nElem);
|
||||
@ -243,8 +243,8 @@ public:
|
||||
|
||||
history.overlap_t_ += Vt*dt;
|
||||
|
||||
real mi = 3*Pi/4*pow(Ri,3.0)*rho_[propId_i];
|
||||
real mj = 3*Pi/4*pow(Rj,3.0)*rho_[propId_j];
|
||||
real mi = 3*Pi/4*pow(Ri,static_cast<real>(3.0))*rho_[propId_i];
|
||||
real mj = 3*Pi/4*pow(Rj,static_cast<real>(3.0))*rho_[propId_j];
|
||||
|
||||
real sqrt_meff = sqrt((mi*mj)/(mi+mj));
|
||||
|
||||
|
@ -131,7 +131,7 @@ protected:
|
||||
// we take out sqrt(meff*K_hertz) here and then consider this term
|
||||
// when calculating damping part.
|
||||
etha_n[i] = -2.2664*log(en[i])/
|
||||
sqrt(pow(log(en[i]),2.0)+ pow(Pi,2.0));
|
||||
sqrt(pow(log(en[i]),static_cast<real>(2.0))+ pow(Pi,static_cast<real>(2.0)));
|
||||
|
||||
// no damping for tangential part
|
||||
|
||||
@ -255,7 +255,7 @@ public:
|
||||
// apply friction
|
||||
if(ft > ft_fric)
|
||||
{
|
||||
if( length(history.overlap_t_) >0.0)
|
||||
if( length(history.overlap_t_) >zero)
|
||||
{
|
||||
if constexpr (limited)
|
||||
{
|
||||
|
50
src/Interaction/Models/grainContactForceModels.hpp
Executable file
50
src/Interaction/Models/grainContactForceModels.hpp
Executable file
@ -0,0 +1,50 @@
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __grainContactForceModels_hpp__
|
||||
#define __grainContactForceModels_hpp__
|
||||
|
||||
#include "cGAbsoluteLinearCF.hpp"
|
||||
#include "cGRelativeLinearCF.hpp"
|
||||
#include "cGNonLinearCF.hpp"
|
||||
|
||||
#include "grainRolling.hpp"
|
||||
|
||||
|
||||
|
||||
namespace pFlow::cfModels
|
||||
{
|
||||
|
||||
|
||||
using limitedCGAbsoluteLinearGrainRolling = grainRolling<cGAbsoluteLinear<true>>;
|
||||
using nonLimitedCGAbsoluteLinearGrainRolling = grainRolling<cGAbsoluteLinear<false>>;
|
||||
|
||||
using limitedCGRelativeLinearGrainRolling = grainRolling<cGRelativeLinear<true>>;
|
||||
using nonLimitedCGRelativeLinearGrainRolling = grainRolling<cGRelativeLinear<false>>;
|
||||
|
||||
using limitedCGNonLinearGrainRolling = grainRolling<cGNonLinear<true>>;
|
||||
using nonLimitedCGNonLinearGrainRolling = grainRolling<cGNonLinear<false>>;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //__grainContactForceModels_hpp__
|
119
src/Interaction/Models/rolling/grainRolling.hpp
Executable file
119
src/Interaction/Models/rolling/grainRolling.hpp
Executable file
@ -0,0 +1,119 @@
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __grainRolling_hpp__
|
||||
#define __grainRolling_hpp__
|
||||
|
||||
|
||||
namespace pFlow::cfModels
|
||||
{
|
||||
|
||||
template<typename contactForceModel>
|
||||
class grainRolling
|
||||
:
|
||||
public contactForceModel
|
||||
{
|
||||
public:
|
||||
|
||||
using contactForceStorage =
|
||||
typename contactForceModel::contactForceStorage;
|
||||
|
||||
|
||||
realSymArray_D mur_;
|
||||
|
||||
bool readGrainDict(const dictionary& dict)
|
||||
{
|
||||
auto mur = dict.getVal<realVector>("mur");
|
||||
|
||||
uint32 nMat;
|
||||
|
||||
if(!realSymArray_D::getN(mur.size(),nMat) || nMat != this->numMaterial())
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"wrong number of values supplied in mur. \n";
|
||||
return false;
|
||||
}
|
||||
|
||||
mur_.assign(mur);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
TypeInfoNV(word("normal<"+contactForceModel::TYPENAME()+">"));
|
||||
|
||||
|
||||
grainRolling(int32 nMaterial, const ViewType1D<real>& rho, const dictionary& dict)
|
||||
:
|
||||
contactForceModel(nMaterial, rho, dict),
|
||||
mur_("mur", nMaterial)
|
||||
{
|
||||
if(!readGrainDict(dict))
|
||||
{
|
||||
fatalExit;
|
||||
}
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
void rollingFriction
|
||||
(
|
||||
const real dt,
|
||||
const uint32 i,
|
||||
const uint32 j,
|
||||
const uint32 propId_i,
|
||||
const uint32 propId_j,
|
||||
const real Ri,
|
||||
const real Rj,
|
||||
const real cGFi,
|
||||
const real cGFj,
|
||||
const realx3& wi,
|
||||
const realx3& wj,
|
||||
const realx3& Nij,
|
||||
const realx3& FCn,
|
||||
realx3& Mri,
|
||||
realx3& Mrj
|
||||
)const
|
||||
{
|
||||
|
||||
realx3 w_hat = wi-wj;
|
||||
real w_hat_mag = length(w_hat);
|
||||
|
||||
if( !equal(w_hat_mag,static_cast<real>(0.0)) )
|
||||
w_hat /= w_hat_mag;
|
||||
else
|
||||
w_hat = static_cast<real>(0.0);
|
||||
|
||||
auto Reff = (Ri*Rj)/(Ri+Rj);
|
||||
|
||||
Mri = ( -mur_(propId_i,propId_j) *length(FCn) * Reff ) * w_hat ;
|
||||
|
||||
//removing the normal part
|
||||
// Mri = Mri - ( (Mri .dot. nij)*nij )
|
||||
|
||||
Mrj = -Mri;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -94,10 +94,10 @@ public:
|
||||
realx3 w_hat = wi-wj;
|
||||
real w_hat_mag = length(w_hat);
|
||||
|
||||
if( !equal(w_hat_mag,0.0) )
|
||||
if( !equal(w_hat_mag,static_cast<real>(0.0)) )
|
||||
w_hat /= w_hat_mag;
|
||||
else
|
||||
w_hat = 0.0;
|
||||
w_hat = static_cast<real>(0.0);
|
||||
|
||||
auto Reff = (Ri*Rj)/(Ri+Rj);
|
||||
|
||||
|
@ -80,13 +80,17 @@ public:
|
||||
|
||||
TypeInfoNV("sortedContactList");
|
||||
|
||||
|
||||
explicit sortedContactList(uint32 initialSize =1)
|
||||
sortedContactList(uint32 initialSize =1)
|
||||
:
|
||||
SortedPairs(initialSize),
|
||||
values_("values", SortedPairs::capacity()),
|
||||
sortedPairs0_("sortedPairs0", SortedPairs::capacity()),
|
||||
values0_("values0", SortedPairs::capacity())
|
||||
sortedContactList("sortedContactList", initialSize)
|
||||
{}
|
||||
|
||||
sortedContactList(const word& name, uint32 initialSize =1)
|
||||
:
|
||||
SortedPairs(name, initialSize),
|
||||
values_(groupNames(name, "values"), SortedPairs::capacity()),
|
||||
sortedPairs0_(groupNames(name, "sortedPairs0"), SortedPairs::capacity()),
|
||||
values0_(groupNames(name, "values0"), SortedPairs::capacity())
|
||||
{}
|
||||
|
||||
bool beforeBroadSearch()
|
||||
|
@ -110,11 +110,11 @@ public:
|
||||
|
||||
|
||||
// constructors
|
||||
explicit sortedPairs(uint32 initialSize =1)
|
||||
explicit sortedPairs(const word& name, uint32 initialSize =1)
|
||||
:
|
||||
UnsortedPairs(initialSize),
|
||||
flags_("flags_",UnsortedPairs::capacity()+1),
|
||||
sortedPairs_("sortedPairs_",UnsortedPairs::capacity())
|
||||
flags_( groupNames(name, "flags_"), UnsortedPairs::capacity()+1),
|
||||
sortedPairs_(groupNames(name, "sortedPairs_"), UnsortedPairs::capacity())
|
||||
{}
|
||||
|
||||
|
||||
@ -193,7 +193,7 @@ public:
|
||||
|
||||
if( capacity+1 > flags_.size() )
|
||||
{
|
||||
reallocNoInit(flags_, capacity+1);
|
||||
reallocInit(flags_, capacity+1);
|
||||
}
|
||||
|
||||
// fill the flags
|
||||
@ -219,7 +219,7 @@ public:
|
||||
{
|
||||
// get more space to prevent reallocations in next iterations
|
||||
uint32 len = size_*1.1+1;
|
||||
reallocNoInit(sortedPairs_, len);
|
||||
reallocInit(sortedPairs_, len);
|
||||
}
|
||||
|
||||
Kokkos::parallel_for(
|
||||
@ -231,6 +231,7 @@ public:
|
||||
// - sort paris based on the first and second
|
||||
sort(sortedPairs_, 0, size_ );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -82,11 +82,16 @@ public:
|
||||
TypeInfoNV("unsortedContactList");
|
||||
|
||||
explicit unsortedContactList(uint32 capacity=1)
|
||||
:
|
||||
unsortedContactList("unsortedContactList", capacity)
|
||||
{}
|
||||
|
||||
unsortedContactList(const word& name, uint32 capacity=1)
|
||||
:
|
||||
UnsortedPairs(capacity),
|
||||
values_("values", UnsortedPairs::capacity()),
|
||||
values_(groupNames(name, "values"), UnsortedPairs::capacity()),
|
||||
container0_(capacity),
|
||||
values0_("values0",container0_.capacity())
|
||||
values0_(groupNames(name, "values0"),container0_.capacity())
|
||||
{}
|
||||
|
||||
|
||||
|
@ -194,7 +194,9 @@ public:
|
||||
{
|
||||
uint newCap = container_.capacity()+len;
|
||||
this->clear();
|
||||
//output<<"----------------before "<<capacity()<< " " << size()<<endl;
|
||||
container_.rehash(newCap);
|
||||
//output<<"----------------after "<<capacity()<< " " << size()<<endl;
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_H
|
||||
|
@ -53,6 +53,47 @@ private:
|
||||
|
||||
boundaryContactSearchList csBoundaries_;
|
||||
|
||||
bool BroadSearch(
|
||||
const timeInfo& ti,
|
||||
csPairContainerType& ppPairs,
|
||||
csPairContainerType& pwPairs,
|
||||
bool force = false) override
|
||||
{
|
||||
|
||||
auto position = Particles().pointPosition().deviceViewAll();
|
||||
auto flags = Particles().dynPointStruct().activePointsMaskDevice();
|
||||
auto diam = Particles().boundingSphere().deviceViewAll();
|
||||
|
||||
return ppwContactSearch_().broadSearch(
|
||||
ti.iter(),
|
||||
ti.t(),
|
||||
ti.dt(),
|
||||
ppPairs,
|
||||
pwPairs,
|
||||
position,
|
||||
flags,
|
||||
diam,
|
||||
force
|
||||
);
|
||||
}
|
||||
|
||||
bool BoundaryBroadSearch(
|
||||
uint32 bndryIndex,
|
||||
const timeInfo& ti,
|
||||
csPairContainerType& ppPairs,
|
||||
csPairContainerType& pwPairs,
|
||||
bool force = false)override
|
||||
{
|
||||
return csBoundaries_[bndryIndex].broadSearch(
|
||||
ti.iter(),
|
||||
ti.t(),
|
||||
ti.dt(),
|
||||
ppPairs,
|
||||
pwPairs,
|
||||
force
|
||||
);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
TypeInfoTemplate11("ContactSearch", SearchMethodType);
|
||||
@ -93,7 +134,7 @@ public:
|
||||
ppwContactSearch_ =
|
||||
makeUnique<SearchMethodType>
|
||||
(
|
||||
dict(),
|
||||
csDict,
|
||||
this->extendedDomainBox(),
|
||||
minD,
|
||||
maxD,
|
||||
@ -108,95 +149,19 @@ public:
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
add_vCtor(
|
||||
contactSearch,
|
||||
ContactSearch,
|
||||
dictionary);
|
||||
|
||||
bool enterBroadSearchBoundary(const timeInfo& ti, bool force=false)const override;
|
||||
|
||||
bool broadSearch(
|
||||
uint32 iter,
|
||||
real t,
|
||||
real dt,
|
||||
csPairContainerType& ppPairs,
|
||||
csPairContainerType& pwPairs,
|
||||
bool force = false) override
|
||||
{
|
||||
|
||||
|
||||
ppTimer().start();
|
||||
|
||||
const auto& position = Particles().pointPosition().deviceViewAll();
|
||||
const auto& flags = Particles().dynPointStruct().activePointsMaskDevice();
|
||||
const auto& diam = Particles().boundingSphere().deviceViewAll();
|
||||
|
||||
|
||||
if( !ppwContactSearch_().broadSearch(
|
||||
iter,
|
||||
t,
|
||||
dt,
|
||||
ppPairs,
|
||||
pwPairs,
|
||||
position,
|
||||
flags,
|
||||
diam,
|
||||
force) )
|
||||
{
|
||||
fatalErrorInFunction;
|
||||
return false;
|
||||
}
|
||||
ppTimer().end();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool boundaryBroadSearch(
|
||||
uint32 i,
|
||||
uint32 iter,
|
||||
real t,
|
||||
real dt,
|
||||
csPairContainerType& ppPairs,
|
||||
csPairContainerType& pwPairs,
|
||||
bool force = false)override
|
||||
{
|
||||
if(i==0u)
|
||||
Particles().boundingSphere().updateBoundaries(DataDirection::SlaveToMaster);
|
||||
return csBoundaries_[i].broadSearch(
|
||||
iter,
|
||||
t,
|
||||
dt,
|
||||
ppPairs,
|
||||
pwPairs,
|
||||
force);
|
||||
}
|
||||
|
||||
bool enterBroadSearch(uint32 iter, real t, real dt)const override
|
||||
{
|
||||
if(ppwContactSearch_)
|
||||
{
|
||||
return ppwContactSearch_().performSearch(iter);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool performedBroadSearch()const override
|
||||
{
|
||||
return ppwContactSearch_().performedSearch();
|
||||
}
|
||||
|
||||
|
||||
uint32 updateInterval()const override
|
||||
{
|
||||
return ppwContactSearch_().updateInterval();
|
||||
}
|
||||
|
||||
real sizeRatio()const override
|
||||
{
|
||||
return ppwContactSearch_().sizeRatio();
|
||||
}
|
||||
|
||||
|
||||
real cellExtent()const override
|
||||
{
|
||||
return ppwContactSearch_().cellExtent();
|
||||
@ -204,7 +169,12 @@ public:
|
||||
|
||||
};
|
||||
|
||||
template <class searchMethod>
|
||||
inline bool ContactSearch<searchMethod>::enterBroadSearchBoundary(const timeInfo &ti, bool force) const
|
||||
{
|
||||
return performSearch(ti.iter(),force) || csBoundaries_.boundariesUpdated();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif //__ContactSearch_hpp__
|
||||
|
@ -73,9 +73,7 @@ public:
|
||||
}
|
||||
|
||||
bool hearChanges(
|
||||
real t,
|
||||
real dt,
|
||||
uint32 iter,
|
||||
const timeInfo& ti,
|
||||
const message &msg,
|
||||
const anyList &varList) override
|
||||
{
|
||||
@ -83,8 +81,10 @@ public:
|
||||
if (msg.equivalentTo(message::BNDR_RESET))
|
||||
{
|
||||
// do nothing
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
fatalErrorInFunction;
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool broadSearch(
|
||||
@ -98,6 +98,11 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isActive()const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static uniquePtr<boundaryContactSearch> create(
|
||||
const dictionary &dict,
|
||||
const boundaryBase &boundary,
|
||||
|
@ -1,3 +1,23 @@
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include "boundaryContactSearchList.hpp"
|
||||
#include "boundaryList.hpp"
|
||||
|
||||
@ -5,7 +25,7 @@ void pFlow::boundaryContactSearchList::setList(
|
||||
const dictionary &dict,
|
||||
const contactSearch &cSearch)
|
||||
{
|
||||
for(auto i=0; i<boundaries_.size(); i++)
|
||||
ForAllBoundariesPtr(i, this)
|
||||
{
|
||||
this->set
|
||||
(
|
||||
@ -20,10 +40,13 @@ pFlow::boundaryContactSearchList::boundaryContactSearchList(
|
||||
const boundaryList& bndrs,
|
||||
const contactSearch &cSearch)
|
||||
:
|
||||
ListPtr(bndrs.size()),
|
||||
boundaryListPtr(),
|
||||
boundaries_(bndrs)
|
||||
{
|
||||
setList(dict, cSearch);
|
||||
}
|
||||
|
||||
|
||||
bool pFlow::boundaryContactSearchList::boundariesUpdated() const
|
||||
{
|
||||
return boundaries_.boundariesUpdated();
|
||||
}
|
||||
|
@ -1,4 +1,24 @@
|
||||
#include "ListPtr.hpp"
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include "boundaryListPtr.hpp"
|
||||
#include "boundaryContactSearch.hpp"
|
||||
|
||||
namespace pFlow
|
||||
@ -9,7 +29,7 @@ class contactSearch;
|
||||
|
||||
class boundaryContactSearchList
|
||||
:
|
||||
public ListPtr<boundaryContactSearch>
|
||||
public boundaryListPtr<boundaryContactSearch>
|
||||
{
|
||||
private:
|
||||
|
||||
@ -28,6 +48,14 @@ public:
|
||||
const contactSearch& cSearch);
|
||||
|
||||
~boundaryContactSearchList()=default;
|
||||
|
||||
inline
|
||||
const boundaryList& boundaries()const
|
||||
{
|
||||
return boundaries_;
|
||||
}
|
||||
|
||||
bool boundariesUpdated()const;
|
||||
|
||||
};
|
||||
|
||||
|
@ -74,6 +74,11 @@ public:
|
||||
csPairContainerType &ppPairs,
|
||||
csPairContainerType &pwPairs,
|
||||
bool force = false) override;
|
||||
|
||||
bool isActive()const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ pFlow::wallBoundaryContactSearch::wallBoundaryContactSearch
|
||||
const ViewType1D<realx3, memory_space> &normals
|
||||
)
|
||||
:
|
||||
cellExtent_( max(cellExtent, 0.5 ) ),
|
||||
cellExtent_( max(cellExtent, half ) ),
|
||||
numElements_(numElements),
|
||||
numPoints_(numPoints),
|
||||
vertices_(vertices),
|
||||
|
@ -31,11 +31,11 @@ pFlow::contactSearch::contactSearch(
|
||||
Timers& timers)
|
||||
:
|
||||
extendedDomainBox_(extDomain),
|
||||
updateInterval_(dict.getValMax<uint32>("updateInterval", 1u)),
|
||||
particles_(prtcl),
|
||||
geometry_(geom),
|
||||
ppTimer_("particle-particle contact search", &timers),
|
||||
pwTimer_("particle-wall contact search", &timers),
|
||||
dict_(dict)
|
||||
bTimer_("Boundary particles contact search", &timers),
|
||||
ppTimer_("Internal particles contact search", &timers)
|
||||
{
|
||||
|
||||
}
|
||||
@ -45,6 +45,78 @@ const pFlow::pointStructure &pFlow::contactSearch::pStruct() const
|
||||
return particles_.pStruct();
|
||||
}
|
||||
|
||||
bool pFlow::contactSearch::broadSearch
|
||||
(
|
||||
const timeInfo &ti,
|
||||
csPairContainerType &ppPairs,
|
||||
csPairContainerType &pwPairs,
|
||||
bool force
|
||||
)
|
||||
{
|
||||
|
||||
if(enterBroadSearch(ti, force))
|
||||
{
|
||||
ppTimer_.start();
|
||||
if( !BroadSearch(
|
||||
ti,
|
||||
ppPairs,
|
||||
pwPairs,
|
||||
force ) )
|
||||
{
|
||||
fatalErrorInFunction;
|
||||
performedSearch_ = false;
|
||||
return false;
|
||||
}
|
||||
ppTimer_.end();
|
||||
performedSearch_ = true;
|
||||
lastUpdated_ = ti.currentIter();
|
||||
}
|
||||
else
|
||||
{
|
||||
performedSearch_ = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pFlow::contactSearch::boundaryBroadSearch
|
||||
(
|
||||
uint32 bndryIndex,
|
||||
const timeInfo &ti,
|
||||
csPairContainerType &ppPairs,
|
||||
csPairContainerType &pwPairs,
|
||||
bool force
|
||||
)
|
||||
{
|
||||
if(enterBroadSearchBoundary(ti, force))
|
||||
{
|
||||
bTimer_.start();
|
||||
for(uint32 i=0u; i<6u; i++)
|
||||
{
|
||||
//output<<" boundarySearch "<< i <<" for iter "<< ti.iter()<<endl;
|
||||
if(!BoundaryBroadSearch(
|
||||
i,
|
||||
ti,
|
||||
ppPairs,
|
||||
pwPairs,
|
||||
force))
|
||||
{
|
||||
performedSearchBoundary_ = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bTimer_.end();
|
||||
performedSearchBoundary_ = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
performedSearchBoundary_ = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
pFlow::uniquePtr<pFlow::contactSearch> pFlow::contactSearch::create(
|
||||
const dictionary &dict,
|
||||
const box &extDomain,
|
||||
|
@ -26,6 +26,7 @@ Licence:
|
||||
#include "contactSearchGlobals.hpp"
|
||||
#include "dictionary.hpp"
|
||||
#include "virtualConstructor.hpp"
|
||||
#include "timeInfo.hpp"
|
||||
#include "Timer.hpp"
|
||||
|
||||
namespace pFlow
|
||||
@ -44,15 +45,44 @@ private:
|
||||
|
||||
const box& extendedDomainBox_;
|
||||
|
||||
/// @brief update interval in terms of iteration numebr
|
||||
uint32 updateInterval_= 1;
|
||||
|
||||
/// @brief last iteration number which contact search has been performed
|
||||
uint32 lastUpdated_ = 0;
|
||||
|
||||
/// @brief performed search?
|
||||
bool performedSearch_ = false;
|
||||
|
||||
/// @brief performed search in boundaries
|
||||
bool performedSearchBoundary_ = false;
|
||||
|
||||
/// const ref to particles
|
||||
const particles& particles_;
|
||||
|
||||
/// const ref to geometry
|
||||
const geometry& geometry_;
|
||||
|
||||
Timer bTimer_;
|
||||
|
||||
Timer ppTimer_;
|
||||
|
||||
Timer pwTimer_;
|
||||
virtual
|
||||
bool BroadSearch(
|
||||
const timeInfo& ti,
|
||||
csPairContainerType& ppPairs,
|
||||
csPairContainerType& pwPairs,
|
||||
bool force
|
||||
)=0;
|
||||
|
||||
dictionary dict_;
|
||||
virtual
|
||||
bool BoundaryBroadSearch(
|
||||
uint32 bndryIndex,
|
||||
const timeInfo& ti,
|
||||
csPairContainerType& ppPairs,
|
||||
csPairContainerType& pwPairs,
|
||||
bool force = false
|
||||
)=0;
|
||||
|
||||
public:
|
||||
|
||||
@ -82,66 +112,86 @@ public:
|
||||
(dict, domain, prtcl, geom, timers)
|
||||
);
|
||||
|
||||
|
||||
const auto& dict()const
|
||||
inline
|
||||
bool performedSearch()const
|
||||
{
|
||||
return dict_;
|
||||
return performedSearch_;
|
||||
}
|
||||
|
||||
const auto& extendedDomainBox()const
|
||||
inline
|
||||
bool performedSearchBoundary()const
|
||||
{
|
||||
return performedSearchBoundary_;
|
||||
}
|
||||
|
||||
inline
|
||||
bool performSearch(uint32 iter, bool force = false)const
|
||||
{
|
||||
if((iter-lastUpdated_) % updateInterval_ == 0 || iter == 0 || force )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool enterBroadSearch(const timeInfo& ti, bool force = false)const
|
||||
{
|
||||
return performSearch(ti.iter(), force);
|
||||
}
|
||||
|
||||
virtual
|
||||
bool enterBroadSearchBoundary(const timeInfo& ti, bool force=false)const = 0;
|
||||
|
||||
inline
|
||||
uint32 updateInterval()const
|
||||
{
|
||||
return updateInterval_;
|
||||
}
|
||||
|
||||
inline
|
||||
const box& extendedDomainBox()const
|
||||
{
|
||||
return extendedDomainBox_;
|
||||
}
|
||||
|
||||
const auto& Particles()const
|
||||
inline
|
||||
const particles& Particles()const
|
||||
{
|
||||
return particles_;
|
||||
}
|
||||
|
||||
const pointStructure& pStruct()const;
|
||||
|
||||
const auto& Geometry()const
|
||||
inline
|
||||
const geometry& Geometry()const
|
||||
{
|
||||
return geometry_;
|
||||
}
|
||||
|
||||
auto& ppTimer()
|
||||
inline
|
||||
Timer& ppTimer()
|
||||
{
|
||||
return ppTimer_;
|
||||
}
|
||||
|
||||
auto& pwTimer()
|
||||
inline
|
||||
Timer& bTimer()
|
||||
{
|
||||
return pwTimer_;
|
||||
return bTimer_;
|
||||
}
|
||||
|
||||
virtual
|
||||
|
||||
bool broadSearch(
|
||||
uint32 iter,
|
||||
real t,
|
||||
real dt,
|
||||
const timeInfo& ti,
|
||||
csPairContainerType& ppPairs,
|
||||
csPairContainerType& pwPairs,
|
||||
bool force = false) = 0;
|
||||
bool force = false);
|
||||
|
||||
virtual
|
||||
bool boundaryBroadSearch(
|
||||
uint32 i,
|
||||
uint32 iter,
|
||||
real t,
|
||||
real dt,
|
||||
uint32 bndryIndex,
|
||||
const timeInfo& ti,
|
||||
csPairContainerType& ppPairs,
|
||||
csPairContainerType& pwPairs,
|
||||
bool force = false)=0;
|
||||
|
||||
virtual
|
||||
bool enterBroadSearch(uint32 iter, real t, real dt)const = 0;
|
||||
|
||||
virtual
|
||||
bool performedBroadSearch()const = 0;
|
||||
|
||||
virtual
|
||||
uint32 updateInterval()const = 0;
|
||||
bool force = false);
|
||||
|
||||
virtual
|
||||
real sizeRatio()const = 0;
|
||||
|
@ -44,9 +44,9 @@ pFlow::NBS::NBS
|
||||
position,
|
||||
flags,
|
||||
diam),
|
||||
sizeRatio_(max(dict.getVal<real>("sizeRatio"), 1.0)),
|
||||
cellExtent_(max(dict.getVal<real>("cellExtent"), 0.5)),
|
||||
adjustableBox_(dict.getVal<Logical>("adjustableBox")),
|
||||
sizeRatio_(max(dict.getVal<real>("sizeRatio"), one)),
|
||||
cellExtent_(max(dict.getVal<real>("cellExtent"), half)),
|
||||
adjustableBox_(false),//adjustableBox_(dict.getVal<Logical>("adjustableBox")),
|
||||
NBSLevel0_
|
||||
(
|
||||
this->domainBox_,
|
||||
|
@ -31,7 +31,7 @@ pFlow::cellsWallLevel0::cellsWallLevel0
|
||||
const ViewType1D<realx3, memory_space>& normals
|
||||
)
|
||||
:
|
||||
cellExtent_( max(cellExtent, 0.5 ) ),
|
||||
cellExtent_( max(cellExtent, half ) ),
|
||||
numElements_(numElements),
|
||||
numPoints_(numPoints),
|
||||
vertices_(vertices),
|
||||
|
@ -23,7 +23,7 @@ Licence:
|
||||
#include "streams.hpp"
|
||||
|
||||
pFlow::uint32 pFlow::mapperNBS::checkInterval_ = 1000;
|
||||
pFlow::real pFlow::mapperNBS::enlargementFactor_ = 1.1;
|
||||
pFlow::real pFlow::mapperNBS::enlargementFactor_ = 1.5;
|
||||
|
||||
bool pFlow::mapperNBS::setSearchBox
|
||||
(
|
||||
|
@ -21,7 +21,7 @@ Licence:
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include "mapperNBSKernels.hpp"
|
||||
|
||||
#include "streams.hpp"
|
||||
|
||||
void pFlow::mapperNBSKernels::findPointExtends
|
||||
(
|
||||
@ -153,16 +153,19 @@ bool pFlow::mapperNBSKernels::buildLists
|
||||
const pFlagTypeDevice &flags
|
||||
)
|
||||
{
|
||||
|
||||
auto aRange = flags.activeRange();
|
||||
|
||||
auto pp = points;
|
||||
if(flags.isAllActive() )
|
||||
{
|
||||
{
|
||||
Kokkos::parallel_for
|
||||
(
|
||||
"pFlow::mapperNBSKernels::buildLists",
|
||||
deviceRPolicyStatic(aRange.start(), aRange.end()),
|
||||
LAMBDA_HD(uint32 i)
|
||||
{
|
||||
auto ind = searchCell.pointIndex(points[i]);
|
||||
{
|
||||
auto ind = searchCell.pointIndex(pp[i]);
|
||||
uint32 old = Kokkos::atomic_exchange(&head(ind.x(), ind.y(), ind.z()), i);
|
||||
next[i] = old;
|
||||
}
|
||||
|
@ -31,48 +31,36 @@ pFlow::particleWallContactSearchs<method>::particleWallContactSearchs
|
||||
const ViewType1D<real, memory_space> &diam
|
||||
)
|
||||
:
|
||||
domainBox_(domain),
|
||||
updateInterval_
|
||||
(
|
||||
max(dict.getValOrSet<uint32>("updateInterval", 1),1u)
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
domainBox_(domain)
|
||||
{}
|
||||
|
||||
template <typename method>
|
||||
bool pFlow::particleWallContactSearchs<method>::broadSearch
|
||||
(
|
||||
uint32 iter,
|
||||
real t,
|
||||
real dt,
|
||||
csPairContainerType& ppPairs,
|
||||
csPairContainerType& pwPairs,
|
||||
const deviceViewType1D<realx3>& pointPos,
|
||||
const pFlagTypeDevice& flags,
|
||||
const deviceViewType1D<real>& diameter,
|
||||
bool force
|
||||
)
|
||||
(
|
||||
uint32 iter,
|
||||
real t,
|
||||
real dt,
|
||||
csPairContainerType& ppPairs,
|
||||
csPairContainerType& pwPairs,
|
||||
const deviceViewType1D<realx3>& pointPos,
|
||||
const pFlagTypeDevice& flags,
|
||||
const deviceViewType1D<real>& diameter,
|
||||
bool force
|
||||
)
|
||||
{
|
||||
|
||||
if(!getMethod().impl_broadSearch(
|
||||
ppPairs,
|
||||
pwPairs,
|
||||
pointPos,
|
||||
flags,
|
||||
diameter))
|
||||
{
|
||||
|
||||
performedSearch_ = false;
|
||||
if( !performSearch(iter, force) ) return true;
|
||||
|
||||
if(!getMethod().impl_broadSearch(
|
||||
ppPairs,
|
||||
pwPairs,
|
||||
pointPos,
|
||||
flags,
|
||||
diameter))
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"Error in performing particle-particle broadSearch in method"<<
|
||||
getMethod().typeName()<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
lastUpdated_ = iter;
|
||||
|
||||
performedSearch_ = true;
|
||||
return true;
|
||||
}
|
||||
fatalErrorInFunction<<
|
||||
"Error in performing particle-particle broadSearch in method"<<
|
||||
getMethod().typeName()<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
@ -48,18 +48,6 @@ private:
|
||||
/// @brief box enclosing the simulation domain (local to processor)
|
||||
box domainBox_;
|
||||
|
||||
/*/// @brief box enclosing the area for contact search (region with points)
|
||||
box searchBox_;*/
|
||||
|
||||
/// @brief update interval in terms of iteration numebr
|
||||
uint32 updateInterval_= 1;
|
||||
|
||||
/// @brief last iteration number which contact search has been performed
|
||||
uint32 lastUpdated_ = 0;
|
||||
|
||||
/// @brief performed search?
|
||||
bool performedSearch_ = false;
|
||||
|
||||
protected:
|
||||
|
||||
inline
|
||||
@ -98,25 +86,6 @@ public:
|
||||
const deviceViewType1D<real>& diameter,
|
||||
bool force = false
|
||||
);
|
||||
|
||||
bool performedSearch()const
|
||||
{
|
||||
return performedSearch_;
|
||||
}
|
||||
|
||||
bool performSearch(uint32 iter, bool force = false)const
|
||||
{
|
||||
if((iter-lastUpdated_) % updateInterval_ == 0 || iter == 0 || force )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 updateInterval()const
|
||||
{
|
||||
return updateInterval_;
|
||||
}
|
||||
|
||||
real sizeRatio()const
|
||||
{
|
||||
|
@ -0,0 +1,104 @@
|
||||
#include "boundarySphereInteraction.hpp"
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
template <typename cFM, typename gMM>
|
||||
void pFlow::boundaryGrainInteraction<cFM, gMM>::allocatePPPairs()
|
||||
{
|
||||
ppPairs_.reset(nullptr);
|
||||
ppPairs_ = makeUnique<ContactListType>(1);
|
||||
}
|
||||
|
||||
template <typename cFM, typename gMM>
|
||||
void pFlow::boundaryGrainInteraction<cFM, gMM>::allocatePWPairs()
|
||||
{
|
||||
pwPairs_.reset(nullptr);
|
||||
pwPairs_ = makeUnique<ContactListType>(1);
|
||||
}
|
||||
|
||||
|
||||
template <typename cFM, typename gMM>
|
||||
pFlow::boundaryGrainInteraction<cFM, gMM>::boundaryGrainInteraction(
|
||||
const boundaryBase &boundary,
|
||||
const grainParticles &grnPrtcls,
|
||||
const GeometryMotionModel &geomMotion)
|
||||
: generalBoundary(boundary, grnPrtcls.pStruct(), "", ""),
|
||||
geometryMotion_(geomMotion),
|
||||
grnParticles_(grnPrtcls)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename cFM, typename gMM>
|
||||
pFlow::uniquePtr<pFlow::boundaryGrainInteraction<cFM, gMM>>
|
||||
pFlow::boundaryGrainInteraction<cFM, gMM>::create(
|
||||
const boundaryBase &boundary,
|
||||
const grainParticles &grnPrtcls,
|
||||
const GeometryMotionModel &geomMotion)
|
||||
{
|
||||
word cfTypeName = ContactForceModel::TYPENAME();
|
||||
word gmTypeName = MotionModel::TYPENAME();
|
||||
word bType = boundary.type();
|
||||
|
||||
word boundaryTypeName = angleBracketsNames3(
|
||||
"boundaryGrainInteraction",
|
||||
bType,
|
||||
cfTypeName,
|
||||
gmTypeName);
|
||||
|
||||
word altBTypeName = angleBracketsNames2(
|
||||
"boundaryGrainInteraction",
|
||||
cfTypeName,
|
||||
gmTypeName);
|
||||
|
||||
if (boundaryBasevCtorSelector_.search(boundaryTypeName))
|
||||
{
|
||||
pOutput.space(4) << "Creating boundry type " << Green_Text(boundaryTypeName) <<
|
||||
" for boundary " << boundary.name() << " . . ." << END_REPORT;
|
||||
return boundaryBasevCtorSelector_[boundaryTypeName](
|
||||
boundary,
|
||||
grnPrtcls,
|
||||
geomMotion);
|
||||
}
|
||||
else if(boundaryBasevCtorSelector_[altBTypeName])
|
||||
{
|
||||
// if boundary condition is not implemented, the default is used
|
||||
|
||||
pOutput.space(4) << "Creating boundry type " << Green_Text(altBTypeName) <<
|
||||
" for boundary " << boundary.name() << " . . ." << END_REPORT;
|
||||
return boundaryBasevCtorSelector_[altBTypeName](
|
||||
boundary,
|
||||
grnPrtcls,
|
||||
geomMotion);
|
||||
}
|
||||
else
|
||||
{
|
||||
printKeys
|
||||
(
|
||||
fatalError << "Ctor Selector "<< boundaryTypeName<<
|
||||
" and "<< altBTypeName << " do not exist. \n"
|
||||
<<"Avaiable ones are: \n\n"
|
||||
,
|
||||
boundaryBasevCtorSelector_
|
||||
);
|
||||
fatalExit;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
@ -0,0 +1,188 @@
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
#ifndef __boundaryGrainInteraction_hpp__
|
||||
#define __boundaryGrainInteraction_hpp__
|
||||
|
||||
#include "virtualConstructor.hpp"
|
||||
#include "generalBoundary.hpp"
|
||||
#include "sortedContactList.hpp"
|
||||
#include "grainParticles.hpp"
|
||||
|
||||
namespace pFlow
|
||||
{
|
||||
|
||||
template<typename contactForceModel,typename geometryMotionModel>
|
||||
class boundaryGrainInteraction
|
||||
:
|
||||
public generalBoundary
|
||||
{
|
||||
public:
|
||||
|
||||
using BoundaryGrainInteractionType
|
||||
= boundaryGrainInteraction<contactForceModel, geometryMotionModel>;
|
||||
|
||||
using GeometryMotionModel = geometryMotionModel;
|
||||
|
||||
using ContactForceModel = contactForceModel;
|
||||
|
||||
using MotionModel = typename geometryMotionModel::MotionModel;
|
||||
|
||||
using ModelStorage = typename ContactForceModel::contactForceStorage;
|
||||
|
||||
using IdType = uint32;
|
||||
|
||||
using IndexType = uint32;
|
||||
|
||||
using ContactListType =
|
||||
sortedContactList<ModelStorage, DefaultExecutionSpace, IdType>;
|
||||
|
||||
private:
|
||||
|
||||
const GeometryMotionModel& geometryMotion_;
|
||||
|
||||
/// const reference to sphere particles
|
||||
const grainParticles& grnParticles_;
|
||||
|
||||
uniquePtr<ContactListType> ppPairs_ = nullptr;
|
||||
|
||||
uniquePtr<ContactListType> pwPairs_ = nullptr;
|
||||
|
||||
protected:
|
||||
|
||||
void allocatePPPairs();
|
||||
|
||||
void allocatePWPairs();
|
||||
|
||||
public:
|
||||
|
||||
TypeInfoTemplate12("boundaryGrainInteraction", ContactForceModel, MotionModel);
|
||||
|
||||
boundaryGrainInteraction(
|
||||
const boundaryBase& boundary,
|
||||
const grainParticles& grnPrtcls,
|
||||
const GeometryMotionModel& geomMotion);
|
||||
|
||||
create_vCtor
|
||||
(
|
||||
BoundaryGrainInteractionType,
|
||||
boundaryBase,
|
||||
(
|
||||
const boundaryBase& boundary,
|
||||
const grainParticles& grnPrtcls,
|
||||
const GeometryMotionModel& geomMotion
|
||||
),
|
||||
(boundary, grnPrtcls, geomMotion)
|
||||
);
|
||||
|
||||
add_vCtor
|
||||
(
|
||||
BoundaryGrainInteractionType,
|
||||
BoundaryGrainInteractionType,
|
||||
boundaryBase
|
||||
);
|
||||
|
||||
~boundaryGrainInteraction()override=default;
|
||||
|
||||
const auto& grnParticles()const
|
||||
{
|
||||
return grnParticles_;
|
||||
}
|
||||
|
||||
const auto& geometryMotion()const
|
||||
{
|
||||
return geometryMotion_;
|
||||
}
|
||||
|
||||
ContactListType& ppPairs()
|
||||
{
|
||||
return ppPairs_();
|
||||
}
|
||||
|
||||
const ContactListType& ppPairs()const
|
||||
{
|
||||
return ppPairs_();
|
||||
}
|
||||
|
||||
ContactListType& pwPairs()
|
||||
{
|
||||
return pwPairs_();
|
||||
}
|
||||
|
||||
const ContactListType& pwPairs()const
|
||||
{
|
||||
return pwPairs_();
|
||||
}
|
||||
|
||||
bool ppPairsAllocated()const
|
||||
{
|
||||
if( ppPairs_)return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool pwPairsAllocated()const
|
||||
{
|
||||
if( pwPairs_)return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual
|
||||
bool grainGrainInteraction(
|
||||
real dt,
|
||||
const ContactForceModel& cfModel,
|
||||
uint32 step)
|
||||
{
|
||||
// for default boundary, no thing to be done
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hearChanges
|
||||
(
|
||||
const timeInfo& ti,
|
||||
const message& msg,
|
||||
const anyList& varList
|
||||
) override
|
||||
{
|
||||
if(msg.equivalentTo(message::BNDR_RESET))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
fatalErrorInFunction<<"Event "<< msg.eventNames() << " is not handled !"<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isActive()const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static
|
||||
uniquePtr<BoundaryGrainInteractionType> create(
|
||||
const boundaryBase& boundary,
|
||||
const grainParticles& sphPrtcls,
|
||||
const GeometryMotionModel& geomMotion
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include "boundaryGrainInteraction.cpp"
|
||||
|
||||
#endif //__boundaryGrainInteraction_hpp__
|
@ -0,0 +1,23 @@
|
||||
|
||||
|
||||
template <typename CFModel, typename gMModel>
|
||||
pFlow::boundaryGrainInteractionList<CFModel, gMModel>::boundaryGrainInteractionList
|
||||
(
|
||||
const grainParticles &grnPrtcls,
|
||||
const gMModel &geomMotion
|
||||
)
|
||||
:
|
||||
boundaryListPtr<boundaryGrainInteraction<CFModel,gMModel>>(),
|
||||
boundaries_(grnPrtcls.pStruct().boundaries())
|
||||
{
|
||||
//gSettings::sleepMiliSeconds(1000*pFlowProcessors().localRank());
|
||||
ForAllBoundariesPtr(i, this)
|
||||
{
|
||||
this->set(
|
||||
i,
|
||||
boundaryGrainInteraction<CFModel, gMModel>::create(
|
||||
boundaries_[i],
|
||||
grnPrtcls,
|
||||
geomMotion));
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
#ifndef __boundaryGrainInteractionList_hpp__
|
||||
#define __boundaryGrainInteractionList_hpp__
|
||||
|
||||
|
||||
#include "boundaryList.hpp"
|
||||
#include "boundaryListPtr.hpp"
|
||||
#include "boundaryGrainInteraction.hpp"
|
||||
|
||||
|
||||
namespace pFlow
|
||||
{
|
||||
|
||||
|
||||
template<typename contactForceModel,typename geometryMotionModel>
|
||||
class boundaryGrainInteractionList
|
||||
:
|
||||
public boundaryListPtr<boundaryGrainInteraction<contactForceModel,geometryMotionModel>>
|
||||
{
|
||||
private:
|
||||
|
||||
const boundaryList& boundaries_;
|
||||
|
||||
public:
|
||||
|
||||
boundaryGrainInteractionList(
|
||||
const grainParticles& grnPrtcls,
|
||||
const geometryMotionModel& geomMotion
|
||||
);
|
||||
|
||||
~boundaryGrainInteractionList()=default;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#include "boundaryGrainInteractionList.cpp"
|
||||
|
||||
#endif //__boundaryGrainInteractionList_hpp__
|
@ -0,0 +1,31 @@
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include "boundaryGrainInteraction.hpp"
|
||||
#include "periodicBoundaryGrainInteraction.hpp"
|
||||
|
||||
#define createBoundaryGrainInteraction(ForceModel,GeomModel) \
|
||||
template class pFlow::boundaryGrainInteraction< \
|
||||
ForceModel, \
|
||||
GeomModel>; \
|
||||
\
|
||||
template class pFlow::periodicBoundaryGrainInteraction< \
|
||||
ForceModel, \
|
||||
GeomModel>;
|
||||
|
@ -0,0 +1,70 @@
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include "periodicBoundarySIKernels.hpp"
|
||||
|
||||
template <typename cFM, typename gMM>
|
||||
pFlow::periodicBoundaryGrainInteraction<cFM, gMM>::periodicBoundaryGrainInteraction(
|
||||
const boundaryBase &boundary,
|
||||
const grainParticles &grnPrtcls,
|
||||
const GeometryMotionModel &geomMotion)
|
||||
: boundaryGrainInteraction<cFM,gMM>(boundary, grnPrtcls, geomMotion),
|
||||
transferVec_(boundary.mirrorBoundary().displacementVectroToMirror())
|
||||
{
|
||||
if(boundary.thisBoundaryIndex()%2==1)
|
||||
{
|
||||
masterInteraction_ = true;
|
||||
this->allocatePPPairs();
|
||||
this->allocatePWPairs();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
masterInteraction_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename cFM, typename gMM>
|
||||
bool pFlow::periodicBoundaryGrainInteraction<cFM, gMM>::grainGrainInteraction
|
||||
(
|
||||
real dt,
|
||||
const ContactForceModel &cfModel,
|
||||
uint32 step
|
||||
)
|
||||
{
|
||||
if(!masterInteraction_) return false;
|
||||
|
||||
pFlow::periodicBoundarySIKernels::grainGrainInteraction(
|
||||
dt,
|
||||
this->ppPairs(),
|
||||
cfModel,
|
||||
transferVec_,
|
||||
this->boundary().thisPoints(),
|
||||
this->mirrorBoundary().thisPoints(),
|
||||
this->grnParticles().diameter().deviceViewAll(),
|
||||
this->grnParticles().coarseGrainFactor().deviceViewAll(),
|
||||
this->grnParticles().propertyId().deviceViewAll(),
|
||||
this->grnParticles().velocity().deviceViewAll(),
|
||||
this->grnParticles().rVelocity().deviceViewAll(),
|
||||
this->grnParticles().contactForce().deviceViewAll(),
|
||||
this->grnParticles().contactTorque().deviceViewAll());
|
||||
|
||||
return false;
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __periodicBoundaryGrainInteraction_hpp__
|
||||
#define __periodicBoundaryGrainInteraction_hpp__
|
||||
|
||||
#include "boundaryGrainInteraction.hpp"
|
||||
|
||||
namespace pFlow
|
||||
{
|
||||
|
||||
template<typename contactForceModel,typename geometryMotionModel>
|
||||
class periodicBoundaryGrainInteraction
|
||||
:
|
||||
public boundaryGrainInteraction<contactForceModel, geometryMotionModel>
|
||||
{
|
||||
public:
|
||||
|
||||
using PBSInteractionType =
|
||||
periodicBoundaryGrainInteraction<contactForceModel,geometryMotionModel>;
|
||||
|
||||
using BSInteractionType =
|
||||
boundaryGrainInteraction<contactForceModel, geometryMotionModel>;
|
||||
|
||||
using GeometryMotionModel = typename BSInteractionType::GeometryMotionModel;
|
||||
|
||||
using ContactForceModel = typename BSInteractionType::ContactForceModel;
|
||||
|
||||
using MotionModel = typename geometryMotionModel::MotionModel;
|
||||
|
||||
using ModelStorage = typename ContactForceModel::contactForceStorage;
|
||||
|
||||
using IdType = typename BSInteractionType::IdType;
|
||||
|
||||
using IndexType = typename BSInteractionType::IndexType;
|
||||
|
||||
using ContactListType = typename BSInteractionType::ContactListType;
|
||||
|
||||
private:
|
||||
|
||||
realx3 transferVec_;
|
||||
|
||||
bool masterInteraction_;
|
||||
public:
|
||||
|
||||
TypeInfoTemplate22("boundaryGrainInteraction", "periodic",ContactForceModel, MotionModel);
|
||||
|
||||
|
||||
periodicBoundaryGrainInteraction(
|
||||
const boundaryBase& boundary,
|
||||
const grainParticles& grnPrtcls,
|
||||
const GeometryMotionModel& geomMotion
|
||||
);
|
||||
|
||||
add_vCtor
|
||||
(
|
||||
BSInteractionType,
|
||||
PBSInteractionType,
|
||||
boundaryBase
|
||||
);
|
||||
|
||||
~periodicBoundaryGrainInteraction()override = default;
|
||||
|
||||
bool grainGrainInteraction(
|
||||
real dt,
|
||||
const ContactForceModel& cfModel,
|
||||
uint32 step)override;
|
||||
|
||||
bool isActive()const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include "periodicBoundaryGrainInteraction.cpp"
|
||||
|
||||
|
||||
#endif //__periodicBoundaryGrainInteraction_hpp__
|
@ -0,0 +1,121 @@
|
||||
|
||||
namespace pFlow::periodicBoundarySIKernels
|
||||
{
|
||||
|
||||
template<typename ContactListType, typename ContactForceModel>
|
||||
inline
|
||||
void grainGrainInteraction
|
||||
(
|
||||
real dt,
|
||||
const ContactListType& cntctList,
|
||||
const ContactForceModel& forceModel,
|
||||
const realx3& transferVec,
|
||||
const deviceScatteredFieldAccess<realx3>& thisPoints,
|
||||
const deviceScatteredFieldAccess<realx3>& mirrorPoints,
|
||||
const deviceViewType1D<real>& diam,
|
||||
const deviceViewType1D<real>& coarseGrainFactor,
|
||||
const deviceViewType1D<uint32>& propId,
|
||||
const deviceViewType1D<realx3>& vel,
|
||||
const deviceViewType1D<realx3>& rVel,
|
||||
const deviceViewType1D<realx3>& cForce,
|
||||
const deviceViewType1D<realx3>& cTorque
|
||||
)
|
||||
{
|
||||
|
||||
using ValueType = typename ContactListType::ValueType;
|
||||
uint32 ss = cntctList.size();
|
||||
uint32 lastItem = cntctList.loopCount();
|
||||
if(lastItem == 0u)return;
|
||||
|
||||
Kokkos::parallel_for(
|
||||
"pFlow::periodicBoundarySIKernels::grainGrainInteraction",
|
||||
deviceRPolicyDynamic(0,lastItem),
|
||||
LAMBDA_HD(uint32 n)
|
||||
{
|
||||
|
||||
if(!cntctList.isValid(n))return;
|
||||
|
||||
auto [i,j] = cntctList.getPair(n);
|
||||
uint32 ind_i = thisPoints.index(i);
|
||||
uint32 ind_j = mirrorPoints.index(j);
|
||||
|
||||
real Ri = 0.5*diam[ind_i];
|
||||
real Rj = 0.5*diam[ind_j];
|
||||
real cGFi = coarseGrainFactor[ind_i];
|
||||
real cGFj = coarseGrainFactor[ind_j];
|
||||
realx3 xi = thisPoints.field()[ind_i];
|
||||
realx3 xj = mirrorPoints.field()[ind_j]+transferVec;
|
||||
real dist = length(xj-xi);
|
||||
real ovrlp = (Ri+Rj) - dist;
|
||||
|
||||
if( ovrlp >0.0 )
|
||||
{
|
||||
auto Nij = (xj-xi)/dist;
|
||||
auto wi = rVel[ind_i];
|
||||
auto wj = rVel[ind_j];
|
||||
auto Vr = vel[ind_i] - vel[ind_j] + cross((Ri*wi+Rj*wj), Nij);
|
||||
|
||||
auto history = cntctList.getValue(n);
|
||||
|
||||
int32 propId_i = propId[ind_i];
|
||||
int32 propId_j = propId[ind_j];
|
||||
|
||||
realx3 FCn, FCt, Mri, Mrj, Mij, Mji;
|
||||
|
||||
// calculates contact force
|
||||
forceModel.contactForce(
|
||||
dt, i, j,
|
||||
propId_i, propId_j,
|
||||
Ri, Rj, cGFi , cGFj ,
|
||||
ovrlp,
|
||||
Vr, Nij,
|
||||
history,
|
||||
FCn, FCt);
|
||||
|
||||
forceModel.rollingFriction(
|
||||
dt, i, j,
|
||||
propId_i, propId_j,
|
||||
Ri, Rj, cGFi , cGFj ,
|
||||
wi, wj,
|
||||
Nij,
|
||||
FCn,
|
||||
Mri, Mrj);
|
||||
|
||||
auto M = cross(Nij,FCt);
|
||||
Mij = Ri*M+Mri;
|
||||
Mji = Rj*M+Mrj;
|
||||
|
||||
auto FC = FCn + FCt;
|
||||
|
||||
|
||||
Kokkos::atomic_add(&cForce[ind_i].x_,FC.x_);
|
||||
Kokkos::atomic_add(&cForce[ind_i].y_,FC.y_);
|
||||
Kokkos::atomic_add(&cForce[ind_i].z_,FC.z_);
|
||||
|
||||
Kokkos::atomic_add(&cForce[ind_j].x_,-FC.x_);
|
||||
Kokkos::atomic_add(&cForce[ind_j].y_,-FC.y_);
|
||||
Kokkos::atomic_add(&cForce[ind_j].z_,-FC.z_);
|
||||
|
||||
Kokkos::atomic_add(&cTorque[ind_i].x_, Mij.x_);
|
||||
Kokkos::atomic_add(&cTorque[ind_i].y_, Mij.y_);
|
||||
Kokkos::atomic_add(&cTorque[ind_i].z_, Mij.z_);
|
||||
|
||||
Kokkos::atomic_add(&cTorque[ind_j].x_, Mji.x_);
|
||||
Kokkos::atomic_add(&cTorque[ind_j].y_, Mji.y_);
|
||||
Kokkos::atomic_add(&cTorque[ind_j].z_, Mji.z_);
|
||||
|
||||
|
||||
cntctList.setValue(n,history);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
cntctList.setValue(n, ValueType());
|
||||
}
|
||||
|
||||
});
|
||||
Kokkos::fence();
|
||||
}
|
||||
|
||||
|
||||
} //pFlow::periodicBoundarySIKernels
|
@ -0,0 +1,355 @@
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
template<typename cFM,typename gMM,template <class, class, class> class cLT>
|
||||
bool pFlow::grainInteraction<cFM,gMM, cLT>::createGrainInteraction()
|
||||
{
|
||||
|
||||
realVector_D rhoD("densities", this->densities());
|
||||
|
||||
auto modelDict = this->subDict("model");
|
||||
|
||||
forceModel_ = makeUnique<ContactForceModel>(
|
||||
this->numMaterials(),
|
||||
rhoD.deviceView(),
|
||||
modelDict );
|
||||
|
||||
|
||||
uint32 nPrtcl = grnParticles_.size();
|
||||
|
||||
contactSearch_ = contactSearch::create(
|
||||
subDict("contactSearch"),
|
||||
grnParticles_.extendedDomain().domainBox(),
|
||||
grnParticles_,
|
||||
geometryMotion_,
|
||||
timers());
|
||||
|
||||
ppContactList_ = makeUnique<ContactListType>("Grain-Grain",nPrtcl+1);
|
||||
|
||||
pwContactList_ = makeUnique<ContactListType>("Grain-wall",nPrtcl/5+1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<typename cFM,typename gMM,template <class, class, class> class cLT>
|
||||
bool pFlow::grainInteraction<cFM,gMM, cLT>::grainGrainInteraction()
|
||||
{
|
||||
auto lastItem = ppContactList_().loopCount();
|
||||
|
||||
// create the kernel functor
|
||||
pFlow::grainInteractionKernels::ppInteractionFunctor
|
||||
ppInteraction(
|
||||
this->dt(),
|
||||
this->forceModel_(),
|
||||
ppContactList_(), // to be read
|
||||
grnParticles_.diameter().deviceViewAll(),
|
||||
grnParticles_.coarseGrainFactor().deviceViewAll(),
|
||||
grnParticles_.propertyId().deviceViewAll(),
|
||||
grnParticles_.pointPosition().deviceViewAll(),
|
||||
grnParticles_.velocity().deviceViewAll(),
|
||||
grnParticles_.rVelocity().deviceViewAll(),
|
||||
grnParticles_.contactForce().deviceViewAll(),
|
||||
grnParticles_.contactTorque().deviceViewAll()
|
||||
);
|
||||
|
||||
Kokkos::parallel_for(
|
||||
"ppInteraction",
|
||||
rpPPInteraction(0,lastItem),
|
||||
ppInteraction
|
||||
);
|
||||
|
||||
Kokkos::fence();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<typename cFM,typename gMM,template <class, class, class> class cLT>
|
||||
bool pFlow::grainInteraction<cFM,gMM, cLT>::grainWallInteraction()
|
||||
{
|
||||
|
||||
uint32 lastItem = pwContactList_().loopCount();
|
||||
uint32 iter = this->currentIter();
|
||||
real t = this->currentTime();
|
||||
real dt = this->dt();
|
||||
|
||||
pFlow::grainInteractionKernels::pwInteractionFunctor
|
||||
pwInteraction(
|
||||
dt,
|
||||
this->forceModel_(),
|
||||
pwContactList_(),
|
||||
geometryMotion_.getTriangleAccessor(),
|
||||
geometryMotion_.getModel(iter, t, dt) ,
|
||||
grnParticles_.diameter().deviceViewAll() ,
|
||||
grnParticles_.coarseGrainFactor().deviceViewAll() ,
|
||||
grnParticles_.propertyId().deviceViewAll(),
|
||||
grnParticles_.pointPosition().deviceViewAll(),
|
||||
grnParticles_.velocity().deviceViewAll(),
|
||||
grnParticles_.rVelocity().deviceViewAll() ,
|
||||
grnParticles_.contactForce().deviceViewAll(),
|
||||
grnParticles_.contactTorque().deviceViewAll() ,
|
||||
geometryMotion_.triMotionIndex().deviceViewAll(),
|
||||
geometryMotion_.propertyId().deviceViewAll(),
|
||||
geometryMotion_.contactForceWall().deviceViewAll()
|
||||
);
|
||||
|
||||
Kokkos::parallel_for(
|
||||
"",
|
||||
rpPWInteraction(0,lastItem),
|
||||
pwInteraction
|
||||
);
|
||||
|
||||
|
||||
Kokkos::fence();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<typename cFM,typename gMM,template <class, class, class> class cLT>
|
||||
pFlow::grainInteraction<cFM,gMM, cLT>::grainInteraction
|
||||
(
|
||||
systemControl& control,
|
||||
const particles& prtcl,
|
||||
const geometry& geom
|
||||
)
|
||||
:
|
||||
interaction(control, prtcl, geom),
|
||||
geometryMotion_(dynamic_cast<const GeometryMotionModel&>(geom)),
|
||||
grnParticles_(dynamic_cast<const grainParticles&>(prtcl)),
|
||||
boundaryInteraction_(grnParticles_,geometryMotion_),
|
||||
ppInteractionTimer_("grain-graine interaction (internal)", &this->timers()),
|
||||
pwInteractionTimer_("grain-wall interaction (internal)", &this->timers()),
|
||||
boundaryInteractionTimer_("grain-grain interaction (boundary)",&this->timers()),
|
||||
contactListMangementTimer_("list management (interal)", &this->timers()),
|
||||
contactListMangementBoundaryTimer_("list management (boundary)", &this->timers())
|
||||
{
|
||||
|
||||
if(!createGrainInteraction())
|
||||
{
|
||||
fatalExit;
|
||||
}
|
||||
|
||||
for(uint32 i=0; i<6; i++)
|
||||
{
|
||||
activeBoundaries_[i] = boundaryInteraction_[i].ppPairsAllocated();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename cFM,typename gMM,template <class, class, class> class cLT>
|
||||
bool pFlow::grainInteraction<cFM,gMM, cLT>::beforeIteration()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename cFM,typename gMM,template <class, class, class> class cLT>
|
||||
bool pFlow::grainInteraction<cFM,gMM, cLT>::iterate()
|
||||
{
|
||||
|
||||
timeInfo ti = this->TimeInfo();
|
||||
auto iter = ti.iter();
|
||||
auto t = ti.t();
|
||||
auto dt = ti.dt();
|
||||
|
||||
auto& contactSearchRef = contactSearch_();
|
||||
|
||||
bool broadSearch = contactSearchRef.enterBroadSearch(ti);
|
||||
bool broadSearchBoundary = contactSearchRef.enterBroadSearchBoundary(ti);
|
||||
|
||||
/// update boundaries of the fields that are being used by inreaction
|
||||
grnParticles_.diameter().updateBoundaries(DataDirection::SlaveToMaster);
|
||||
grnParticles_.velocity().updateBoundaries(DataDirection::SlaveToMaster);
|
||||
grnParticles_.rVelocity().updateBoundaries(DataDirection::SlaveToMaster);
|
||||
grnParticles_.propertyId().updateBoundaries(DataDirection::SlaveToMaster);
|
||||
|
||||
/// lists
|
||||
if(broadSearch)
|
||||
{
|
||||
contactListMangementTimer_.start();
|
||||
ComputationTimer().start();
|
||||
ppContactList_().beforeBroadSearch();
|
||||
pwContactList_().beforeBroadSearch();
|
||||
ComputationTimer().end();
|
||||
contactListMangementTimer_.pause();
|
||||
}
|
||||
|
||||
if(broadSearchBoundary)
|
||||
{
|
||||
contactListMangementBoundaryTimer_.start();
|
||||
ComputationTimer().start();
|
||||
for(uint32 i=0; i<6u; i++)
|
||||
{
|
||||
if(activeBoundaries_[i])
|
||||
{
|
||||
auto& BI = boundaryInteraction_[i];
|
||||
BI.ppPairs().beforeBroadSearch();
|
||||
BI.pwPairs().beforeBroadSearch();
|
||||
}
|
||||
}
|
||||
ComputationTimer().end();
|
||||
contactListMangementBoundaryTimer_.pause();
|
||||
}
|
||||
|
||||
if( grnParticles_.numActive()<=0)return true;
|
||||
|
||||
ComputationTimer().start();
|
||||
if( !contactSearchRef.broadSearch(
|
||||
ti,
|
||||
ppContactList_(),
|
||||
pwContactList_()) )
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"unable to perform broadSearch.\n";
|
||||
fatalExit;
|
||||
}
|
||||
|
||||
for(uint32 i=0; i<6u; i++)
|
||||
{
|
||||
if(activeBoundaries_[i])
|
||||
{
|
||||
auto& BI = boundaryInteraction_[i];
|
||||
if(!contactSearchRef.boundaryBroadSearch(
|
||||
i,
|
||||
ti,
|
||||
BI.ppPairs(),
|
||||
BI.pwPairs())
|
||||
)
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"failed to perform broadSearch for boundary index "<<i<<endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
ComputationTimer().end();
|
||||
|
||||
if(broadSearch && contactSearchRef.performedSearch())
|
||||
{
|
||||
contactListMangementTimer_.resume();
|
||||
ComputationTimer().start();
|
||||
ppContactList_().afterBroadSearch();
|
||||
pwContactList_().afterBroadSearch();
|
||||
ComputationTimer().end();
|
||||
contactListMangementTimer_.end();
|
||||
}
|
||||
|
||||
if(broadSearchBoundary && contactSearchRef.performedSearchBoundary())
|
||||
{
|
||||
contactListMangementBoundaryTimer_.resume();
|
||||
ComputationTimer().start();
|
||||
for(uint32 i=0; i<6u; i++)
|
||||
{
|
||||
if(activeBoundaries_[i])
|
||||
{
|
||||
auto& BI = boundaryInteraction_[i];
|
||||
BI.ppPairs().afterBroadSearch();
|
||||
BI.pwPairs().afterBroadSearch();
|
||||
}
|
||||
}
|
||||
ComputationTimer().end();
|
||||
contactListMangementBoundaryTimer_.end();
|
||||
}
|
||||
|
||||
/// peform contact search on boundareis with active contact search (master boundaries)
|
||||
auto requireStep = boundariesMask<6>(true);
|
||||
const auto& cfModel = this->forceModel_();
|
||||
uint32 step=1;
|
||||
boundaryInteractionTimer_.start();
|
||||
ComputationTimer().start();
|
||||
while(requireStep.anyElement(true) && step <= 10)
|
||||
{
|
||||
for(uint32 i=0; i<6u; i++)
|
||||
{
|
||||
if(requireStep[i] )
|
||||
{
|
||||
requireStep[i] = boundaryInteraction_[i].grainGrainInteraction(
|
||||
dt,
|
||||
this->forceModel_(),
|
||||
step
|
||||
);
|
||||
}
|
||||
}
|
||||
step++;
|
||||
}
|
||||
ComputationTimer().end();
|
||||
boundaryInteractionTimer_.pause();
|
||||
|
||||
|
||||
ppInteractionTimer_.start();
|
||||
ComputationTimer().start();
|
||||
grainGrainInteraction();
|
||||
ComputationTimer().end();
|
||||
ppInteractionTimer_.end();
|
||||
|
||||
|
||||
pwInteractionTimer_.start();
|
||||
ComputationTimer().start();
|
||||
grainWallInteraction();
|
||||
ComputationTimer().start();
|
||||
pwInteractionTimer_.end();
|
||||
|
||||
{
|
||||
boundaryInteractionTimer_.resume();
|
||||
ComputationTimer().start();
|
||||
auto requireStep = boundariesMask<6>(true);
|
||||
|
||||
uint32 step = 11;
|
||||
const auto& cfModel = this->forceModel_();
|
||||
while( requireStep.anyElement(true) && step < 20 )
|
||||
{
|
||||
for(uint32 i=0; i<6u; i++)
|
||||
{
|
||||
if(requireStep[i])
|
||||
{
|
||||
requireStep[i] = boundaryInteraction_[i].grainGrainInteraction(
|
||||
dt,
|
||||
cfModel,
|
||||
step
|
||||
);
|
||||
}
|
||||
}
|
||||
step++;
|
||||
}
|
||||
ComputationTimer().end();
|
||||
boundaryInteractionTimer_.end();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename cFM,typename gMM,template <class, class, class> class cLT>
|
||||
bool pFlow::grainInteraction<cFM,gMM, cLT>::afterIteration()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename cFM,typename gMM,template <class, class, class> class cLT>
|
||||
bool pFlow::grainInteraction<cFM,gMM, cLT>::hearChanges
|
||||
(
|
||||
const timeInfo& ti,
|
||||
const message& msg,
|
||||
const anyList& varList
|
||||
)
|
||||
{
|
||||
fatalErrorInFunction<<"Event "<< msg.eventNames()<<
|
||||
" is not handled in grainInteraction"<<endl;
|
||||
return false;
|
||||
}
|
@ -0,0 +1,167 @@
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __grainInteraction_hpp__
|
||||
#define __grainInteraction_hpp__
|
||||
|
||||
#include "interaction.hpp"
|
||||
#include "grainParticles.hpp"
|
||||
#include "boundaryGrainInteractionList.hpp"
|
||||
#include "grainInteractionKernels.hpp"
|
||||
#include "boundariesMask.hpp"
|
||||
#include "MPITimer.hpp"
|
||||
//#include "unsortedContactList.hpp"
|
||||
|
||||
|
||||
|
||||
namespace pFlow
|
||||
{
|
||||
|
||||
template<
|
||||
typename contactForceModel,
|
||||
typename geometryMotionModel,
|
||||
template <class, class, class> class contactListType>
|
||||
class grainInteraction
|
||||
:
|
||||
public interaction
|
||||
{
|
||||
public:
|
||||
|
||||
using GeometryMotionModel = geometryMotionModel;
|
||||
|
||||
using ContactForceModel = contactForceModel;
|
||||
|
||||
using MotionModel = typename geometryMotionModel::MotionModel;
|
||||
|
||||
using ModelStorage = typename ContactForceModel::contactForceStorage;
|
||||
|
||||
using BoundaryListType = boundaryGrainInteractionList<ContactForceModel,GeometryMotionModel>;
|
||||
|
||||
using IdType = uint32;
|
||||
|
||||
using IndexType = uint32;
|
||||
|
||||
using ContactListType =
|
||||
contactListType<ModelStorage, DefaultExecutionSpace, IdType>;
|
||||
|
||||
//using BoundaryContactListType = unsortedContactList<ModelStorage, DefaultExecutionSpace, IdType>;
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/// const reference to geometry
|
||||
const GeometryMotionModel& geometryMotion_;
|
||||
|
||||
/// const reference to particles
|
||||
const grainParticles& grnParticles_;
|
||||
|
||||
/// particle-particle and particle-wall interactions at boundaries
|
||||
BoundaryListType boundaryInteraction_;
|
||||
|
||||
/// a mask for active boundaries (boundaries with intreaction)
|
||||
boundariesMask<6> activeBoundaries_;
|
||||
|
||||
/// contact search object for pp and pw interactions
|
||||
uniquePtr<contactSearch> contactSearch_ = nullptr;
|
||||
|
||||
/// contact force model
|
||||
uniquePtr<ContactForceModel> forceModel_ = nullptr;
|
||||
|
||||
/// contact list for particle-particle interactoins (keeps the history)
|
||||
uniquePtr<ContactListType> ppContactList_ = nullptr;
|
||||
|
||||
/// contact list for particle-wall interactions (keeps the history)
|
||||
uniquePtr<ContactListType> pwContactList_ = nullptr;
|
||||
|
||||
|
||||
/// timer for particle-particle interaction computations
|
||||
Timer ppInteractionTimer_;
|
||||
|
||||
/// timer for particle-wall interaction computations
|
||||
Timer pwInteractionTimer_;
|
||||
|
||||
/// timer for boundary interaction time
|
||||
Timer boundaryInteractionTimer_;
|
||||
|
||||
/// timer for managing contact lists (only inernal points)
|
||||
Timer contactListMangementTimer_;
|
||||
|
||||
Timer contactListMangementBoundaryTimer_;
|
||||
|
||||
|
||||
|
||||
bool createGrainInteraction();
|
||||
|
||||
bool grainGrainInteraction();
|
||||
|
||||
bool grainWallInteraction();
|
||||
|
||||
/// range policy for p-p interaction execution
|
||||
using rpPPInteraction =
|
||||
Kokkos::RangePolicy<Kokkos::IndexType<uint32>, Kokkos::Schedule<Kokkos::Dynamic>>;
|
||||
|
||||
/// range policy for p-w interaction execution
|
||||
using rpPWInteraction = rpPPInteraction;
|
||||
|
||||
public:
|
||||
|
||||
TypeInfoTemplate13("grainInteraction", ContactForceModel, MotionModel, ContactListType);
|
||||
|
||||
/// Constructor from components
|
||||
grainInteraction(
|
||||
systemControl& control,
|
||||
const particles& prtcl,
|
||||
const geometry& geom);
|
||||
|
||||
|
||||
/// Add virtual constructor
|
||||
add_vCtor
|
||||
(
|
||||
interaction,
|
||||
grainInteraction,
|
||||
systemControl
|
||||
);
|
||||
|
||||
/// This is called in time loop, before iterate. (overriden from demComponent)
|
||||
bool beforeIteration() override;
|
||||
|
||||
/// This is called in time loop. Perform the main calculations
|
||||
/// when the component should evolve along time. (overriden from demComponent)
|
||||
bool iterate() override;
|
||||
|
||||
/// This is called in time loop, after iterate. (overriden from demComponent)
|
||||
bool afterIteration() override;
|
||||
|
||||
/// Check for changes in the point structures. (overriden from observer)
|
||||
bool hearChanges(
|
||||
const timeInfo& ti,
|
||||
const message& msg,
|
||||
const anyList& varList)override;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#include "grainInteraction.cpp"
|
||||
|
||||
#endif //__grainInteraction_hpp__
|
@ -0,0 +1,337 @@
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __grainInteractionKernels_hpp__
|
||||
#define __grainInteractionKernels_hpp__
|
||||
|
||||
|
||||
#include "grainTriSurfaceContact.hpp"
|
||||
|
||||
namespace pFlow::grainInteractionKernels
|
||||
{
|
||||
|
||||
template<
|
||||
typename ContactForceModel,
|
||||
typename ContactListType>
|
||||
struct ppInteractionFunctor
|
||||
{
|
||||
|
||||
using PairType = typename ContactListType::PairType;
|
||||
using ValueType = typename ContactListType::ValueType;
|
||||
|
||||
real dt_;
|
||||
|
||||
ContactForceModel forceModel_;
|
||||
ContactListType tobeFilled_;
|
||||
|
||||
deviceViewType1D<real> diam_;
|
||||
deviceViewType1D<real> coarseGrainFactor_;
|
||||
deviceViewType1D<uint32> propId_;
|
||||
deviceViewType1D<realx3> pos_;
|
||||
deviceViewType1D<realx3> lVel_;
|
||||
deviceViewType1D<realx3> rVel_;
|
||||
deviceViewType1D<realx3> cForce_;
|
||||
deviceViewType1D<realx3> cTorque_;
|
||||
|
||||
|
||||
ppInteractionFunctor(
|
||||
real dt,
|
||||
ContactForceModel forceModel,
|
||||
ContactListType tobeFilled,
|
||||
deviceViewType1D<real> diam,
|
||||
deviceViewType1D<real> coarseGrainFactor,
|
||||
deviceViewType1D<uint32> propId,
|
||||
deviceViewType1D<realx3> pos,
|
||||
deviceViewType1D<realx3> lVel,
|
||||
deviceViewType1D<realx3> rVel,
|
||||
deviceViewType1D<realx3> cForce,
|
||||
deviceViewType1D<realx3> cTorque )
|
||||
:
|
||||
dt_(dt),
|
||||
forceModel_(forceModel),
|
||||
tobeFilled_(tobeFilled),
|
||||
diam_(diam),
|
||||
coarseGrainFactor_(coarseGrainFactor),
|
||||
propId_(propId),
|
||||
pos_(pos),
|
||||
lVel_(lVel),
|
||||
rVel_(rVel),
|
||||
cForce_(cForce), // this is converted to an atomic vector
|
||||
cTorque_(cTorque) // this is converted to an atomic vector
|
||||
{}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
void operator()(const uint32 n)const
|
||||
{
|
||||
|
||||
if(!tobeFilled_.isValid(n))return;
|
||||
|
||||
auto [i,j] = tobeFilled_.getPair(n);
|
||||
|
||||
real Ri = 0.5*diam_[i];
|
||||
real Rj = 0.5*diam_[j];
|
||||
|
||||
real cGFi = coarseGrainFactor_[j];
|
||||
real cGFj = coarseGrainFactor_[j];
|
||||
|
||||
realx3 xi = pos_[i];
|
||||
realx3 xj = pos_[j];
|
||||
real dist = length(xj-xi);
|
||||
real ovrlp = (Ri+Rj) - dist;
|
||||
|
||||
if( ovrlp >0.0 )
|
||||
{
|
||||
|
||||
auto Vi = lVel_[i];
|
||||
auto Vj = lVel_[j];
|
||||
auto wi = rVel_[i];
|
||||
auto wj = rVel_[j];
|
||||
auto Nij = (xj-xi)/dist;
|
||||
auto Vr = Vi - Vj + cross((Ri*wi+Rj*wj), Nij);
|
||||
|
||||
auto history = tobeFilled_.getValue(n);
|
||||
|
||||
int32 propId_i = propId_[i];
|
||||
int32 propId_j = propId_[j];
|
||||
|
||||
realx3 FCn, FCt, Mri, Mrj, Mij, Mji;
|
||||
|
||||
// calculates contact force
|
||||
forceModel_.contactForce(
|
||||
dt_, i, j,
|
||||
propId_i, propId_j,
|
||||
Ri, Rj, cGFi , cGFj ,
|
||||
ovrlp,
|
||||
Vr, Nij,
|
||||
history,
|
||||
FCn, FCt
|
||||
);
|
||||
|
||||
forceModel_.rollingFriction(
|
||||
dt_, i, j,
|
||||
propId_i, propId_j,
|
||||
Ri, Rj, cGFi , cGFj ,
|
||||
wi, wj,
|
||||
Nij,
|
||||
FCn,
|
||||
Mri, Mrj
|
||||
);
|
||||
|
||||
auto M = cross(Nij,FCt);
|
||||
Mij = Ri*M+Mri;
|
||||
Mji = Rj*M+Mrj;
|
||||
|
||||
auto FC = FCn + FCt;
|
||||
|
||||
Kokkos::atomic_add(&cForce_[i].x_,FC.x_);
|
||||
Kokkos::atomic_add(&cForce_[i].y_,FC.y_);
|
||||
Kokkos::atomic_add(&cForce_[i].z_,FC.z_);
|
||||
|
||||
Kokkos::atomic_add(&cForce_[j].x_,-FC.x_);
|
||||
Kokkos::atomic_add(&cForce_[j].y_,-FC.y_);
|
||||
Kokkos::atomic_add(&cForce_[j].z_,-FC.z_);
|
||||
|
||||
Kokkos::atomic_add(&cTorque_[i].x_, Mij.x_);
|
||||
Kokkos::atomic_add(&cTorque_[i].y_, Mij.y_);
|
||||
Kokkos::atomic_add(&cTorque_[i].z_, Mij.z_);
|
||||
|
||||
Kokkos::atomic_add(&cTorque_[j].x_, Mji.x_);
|
||||
Kokkos::atomic_add(&cTorque_[j].y_, Mji.y_);
|
||||
Kokkos::atomic_add(&cTorque_[j].z_, Mji.z_);
|
||||
|
||||
|
||||
tobeFilled_.setValue(n,history);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
tobeFilled_.setValue(n, ValueType());
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<
|
||||
typename ContactForceModel,
|
||||
typename ContactListType,
|
||||
typename TraingleAccessor,
|
||||
typename MotionModel>
|
||||
struct pwInteractionFunctor
|
||||
{
|
||||
using PairType = typename ContactListType::PairType;
|
||||
using ValueType = typename ContactListType::ValueType;
|
||||
|
||||
real dt_;
|
||||
|
||||
ContactForceModel forceModel_;
|
||||
ContactListType tobeFilled_;
|
||||
|
||||
TraingleAccessor triangles_;
|
||||
MotionModel motionModel_;
|
||||
|
||||
deviceViewType1D<real> diam_;
|
||||
deviceViewType1D<real> coarseGrainFactor_;
|
||||
deviceViewType1D<uint32> propId_;
|
||||
deviceViewType1D<realx3> pos_;
|
||||
deviceViewType1D<realx3> lVel_;
|
||||
deviceViewType1D<realx3> rVel_;
|
||||
deviceViewType1D<realx3> cForce_;
|
||||
deviceViewType1D<realx3> cTorque_;
|
||||
deviceViewType1D<uint32> wTriMotionIndex_;
|
||||
deviceViewType1D<uint32> wPropId_;
|
||||
deviceViewType1D<realx3> wCForce_;
|
||||
|
||||
|
||||
pwInteractionFunctor(
|
||||
real dt,
|
||||
ContactForceModel forceModel,
|
||||
ContactListType tobeFilled,
|
||||
TraingleAccessor triangles,
|
||||
MotionModel motionModel ,
|
||||
deviceViewType1D<real> diam ,
|
||||
deviceViewType1D<real> coarseGrainFactor,
|
||||
deviceViewType1D<uint32> propId,
|
||||
deviceViewType1D<realx3> pos ,
|
||||
deviceViewType1D<realx3> lVel,
|
||||
deviceViewType1D<realx3> rVel,
|
||||
deviceViewType1D<realx3> cForce,
|
||||
deviceViewType1D<realx3> cTorque ,
|
||||
deviceViewType1D<uint32> wTriMotionIndex,
|
||||
deviceViewType1D<uint32> wPropId,
|
||||
deviceViewType1D<realx3> wCForce)
|
||||
:
|
||||
dt_(dt),
|
||||
forceModel_(forceModel),
|
||||
tobeFilled_(tobeFilled),
|
||||
triangles_(triangles) ,
|
||||
motionModel_(motionModel) ,
|
||||
diam_(diam) ,
|
||||
coarseGrainFactor_(coarseGrainFactor),
|
||||
propId_(propId),
|
||||
pos_(pos) ,
|
||||
lVel_(lVel),
|
||||
rVel_(rVel) ,
|
||||
cForce_(cForce),
|
||||
cTorque_(cTorque) ,
|
||||
wTriMotionIndex_(wTriMotionIndex) ,
|
||||
wPropId_(wPropId),
|
||||
wCForce_(wCForce)
|
||||
{}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
void operator()(const int32 n)const
|
||||
{
|
||||
|
||||
if(!tobeFilled_.isValid(n))return;
|
||||
|
||||
auto [i,tj] = tobeFilled_.getPair(n);
|
||||
|
||||
real Ri = 0.5*diam_[i];
|
||||
real Rj = 10000.0;
|
||||
real cGFi = coarseGrainFactor_[i];
|
||||
real cGFj = coarseGrainFactor_[i];
|
||||
realx3 xi = pos_[i];
|
||||
|
||||
realx3x3 tri = triangles_(tj);
|
||||
real ovrlp;
|
||||
realx3 Nij, cp;
|
||||
|
||||
if( pFlow::grnTriInteraction::isGrainInContactBothSides(
|
||||
tri, xi, Ri, ovrlp, Nij, cp) )
|
||||
{
|
||||
auto Vi = lVel_[i];
|
||||
auto wi = rVel_[i];
|
||||
|
||||
int32 mInd = wTriMotionIndex_[tj];
|
||||
|
||||
auto Vw = motionModel_(mInd, cp);
|
||||
|
||||
//output<< "par-wall index "<< i<<" - "<< tj<<endl;
|
||||
|
||||
auto Vr = Vi - Vw + cross(Ri*wi, Nij);
|
||||
|
||||
auto history = tobeFilled_.getValue(n);
|
||||
|
||||
int32 propId_i = propId_[i];
|
||||
int32 wPropId_j = wPropId_[tj];
|
||||
|
||||
realx3 FCn, FCt, Mri, Mrj, Mij;
|
||||
//output<< "before "<<history.overlap_t_<<endl;
|
||||
// calculates contact force
|
||||
forceModel_.contactForce(
|
||||
dt_, i, tj,
|
||||
propId_i, wPropId_j,
|
||||
Ri, Rj, cGFi , cGFj ,
|
||||
ovrlp,
|
||||
Vr, Nij,
|
||||
history,
|
||||
FCn, FCt
|
||||
);
|
||||
|
||||
//output<< "after "<<history.overlap_t_<<endl;
|
||||
|
||||
forceModel_.rollingFriction(
|
||||
dt_, i, tj,
|
||||
propId_i, wPropId_j,
|
||||
Ri, Rj, cGFi , cGFj ,
|
||||
wi, 0.0,
|
||||
Nij,
|
||||
FCn,
|
||||
Mri, Mrj
|
||||
);
|
||||
|
||||
auto M = cross(Nij,FCt);
|
||||
Mij = Ri*M+Mri;
|
||||
//output<< "FCt = "<<FCt <<endl;
|
||||
//output<< "FCn = "<<FCn <<endl;
|
||||
//output<<"propId i, tj"<< propId_i << " "<<wPropId_j<<endl;
|
||||
//output<<"par i , wj"<< i<<" "<< tj<<endl;
|
||||
|
||||
auto FC = FCn + FCt;
|
||||
|
||||
Kokkos::atomic_add(&cForce_[i].x_,FC.x_);
|
||||
Kokkos::atomic_add(&cForce_[i].y_,FC.y_);
|
||||
Kokkos::atomic_add(&cForce_[i].z_,FC.z_);
|
||||
|
||||
Kokkos::atomic_add(&wCForce_[tj].x_,-FC.x_);
|
||||
Kokkos::atomic_add(&wCForce_[tj].y_,-FC.y_);
|
||||
Kokkos::atomic_add(&wCForce_[tj].z_,-FC.z_);
|
||||
|
||||
|
||||
Kokkos::atomic_add(&cTorque_[i].x_, Mij.x_);
|
||||
Kokkos::atomic_add(&cTorque_[i].y_, Mij.y_);
|
||||
Kokkos::atomic_add(&cTorque_[i].z_, Mij.z_);
|
||||
|
||||
tobeFilled_.setValue(n,history);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
tobeFilled_.setValue(n,ValueType());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //__grainInteractionKernels_hpp__
|
@ -0,0 +1,231 @@
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __grainTriSurfaceContact_hpp__
|
||||
#define __grainTriSurfaceContact_hpp__
|
||||
|
||||
#include "triWall.hpp"
|
||||
#include "pLine.hpp"
|
||||
|
||||
namespace pFlow::grnTriInteraction
|
||||
{
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
bool pointInPlane(
|
||||
const realx3& p1,
|
||||
const realx3& p2,
|
||||
const realx3& p3,
|
||||
const realx3& p )
|
||||
{
|
||||
|
||||
realx3 p1p = p1 - p;
|
||||
realx3 p2p = p2 - p;
|
||||
realx3 p3p = p3 - p;
|
||||
|
||||
real p1p2 = dot(p1p, p2p);
|
||||
real p2p3 = dot(p2p, p3p);
|
||||
real p2p2 = dot(p2p, p2p);
|
||||
real p1p3 = dot(p1p, p3p);
|
||||
|
||||
// first condition u.v < 0
|
||||
// u.v = [(p1-p)x(p2-p)].[(p2-p)x(p3-p)] = (p1p.p2p)(p2p.p3p) - (p2p.p2p)(p1p.p3p)
|
||||
if (p1p2*p2p3 - p2p2*p1p3 < 0.0) return false;
|
||||
|
||||
|
||||
// second condition u.w < 0
|
||||
// u.w = [(p1-p)x(p2-p)].[(p3-p)x(p1-p)] = (p1p.p3p)(p2p.p1p) - (p2p.p3p)(p1p.p1p)
|
||||
real p1p1 = dot(p1p, p1p);
|
||||
if (p1p3*p1p2 - p2p3*p1p1 < (0.0)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
void cramerRule2(real A[2][2], real B[2], real & x1, real &x2)
|
||||
{
|
||||
real det = (A[0][0] * A[1][1] - A[1][0]*A[0][1]);
|
||||
x1 = (B[0]*A[1][1] - B[1]*A[0][1]) / det;
|
||||
x2 = (A[0][0] * B[1] - A[1][0] * B[0])/ det;
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
bool pointInPlane(
|
||||
const realx3& p1,
|
||||
const realx3& p2,
|
||||
const realx3& p3,
|
||||
const realx3 &p,
|
||||
int32 &Ln)
|
||||
{
|
||||
realx3 v0 = p2 - p1;
|
||||
realx3 v1 = p3 - p1;
|
||||
realx3 v2 = p - p1;
|
||||
|
||||
real A[2][2] = { dot(v0, v0), dot(v0, v1), dot(v1, v0), dot(v1, v1) };
|
||||
real B[2] = { dot(v0, v2), dot(v1, v2) };
|
||||
real nu, w;
|
||||
|
||||
cramerRule2(A, B, nu, w);
|
||||
real nuW = nu + w;
|
||||
|
||||
|
||||
if (nuW > 1)
|
||||
{
|
||||
Ln = 2; return true;
|
||||
}
|
||||
else if (nuW >= 0)
|
||||
{
|
||||
if (nu >= 0 && w >= 0)
|
||||
{
|
||||
Ln = 0; return true;
|
||||
}
|
||||
if (nu > 0 && w < 0)
|
||||
{
|
||||
Ln = 1; return true;
|
||||
}
|
||||
if (nu < 0 && w > 0)
|
||||
{
|
||||
Ln = 3; return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Ln = 1; return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
bool isGrainInContactActiveSide(
|
||||
const realx3& p1,
|
||||
const realx3& p2,
|
||||
const realx3& p3,
|
||||
const realx3& cntr,
|
||||
real rad,
|
||||
real& ovrlp,
|
||||
realx3& norm,
|
||||
realx3& cp)
|
||||
{
|
||||
|
||||
triWall wall(true, p1,p2,p3);
|
||||
|
||||
real dist = wall.normalDistFromWall(cntr);
|
||||
|
||||
if(dist < 0.0 )return false;
|
||||
|
||||
ovrlp = rad - dist;
|
||||
|
||||
if (ovrlp > 0)
|
||||
{
|
||||
realx3 ptOnPlane = wall.nearestPointOnWall(cntr);
|
||||
|
||||
if (pointInPlane(p1, p2, p3, ptOnPlane))
|
||||
{
|
||||
cp = ptOnPlane;
|
||||
norm = -wall.n_;
|
||||
return true;
|
||||
}
|
||||
|
||||
realx3 lnv;
|
||||
|
||||
if (pLine(p1,p2).lineGrainCheck(cntr, rad, lnv, cp, ovrlp))
|
||||
{
|
||||
norm = -lnv;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( pLine(p2,p3).lineGrainCheck(cntr, rad, lnv, cp, ovrlp))
|
||||
{
|
||||
norm = -lnv;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( pLine(p3,p1).lineGrainCheck(cntr, rad, lnv, cp, ovrlp))
|
||||
{
|
||||
norm = -lnv;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
bool isGrainInContactBothSides(
|
||||
const realx3x3& tri,
|
||||
const realx3& cntr,
|
||||
real Rad,
|
||||
real& ovrlp,
|
||||
realx3& norm,
|
||||
realx3& cp)
|
||||
{
|
||||
|
||||
triWall wall(true, tri.x_,tri.y_,tri.z_);
|
||||
|
||||
real dist = wall.normalDistFromWall(cntr);
|
||||
|
||||
|
||||
ovrlp = Rad - abs(dist);
|
||||
|
||||
if (ovrlp > 0)
|
||||
{
|
||||
realx3 ptOnPlane = wall.nearestPointOnWall(cntr);
|
||||
|
||||
if (pointInPlane(tri.x_,tri.y_,tri.z_,ptOnPlane))
|
||||
{
|
||||
cp = ptOnPlane;
|
||||
|
||||
if(dist >= 0.0)
|
||||
norm = -wall.n_;
|
||||
else
|
||||
norm = wall.n_;
|
||||
return true;
|
||||
}
|
||||
|
||||
realx3 lnv;
|
||||
|
||||
if (pLine(tri.x_, tri.y_).lineGrainCheck(cntr, Rad, lnv, cp, ovrlp))
|
||||
{
|
||||
norm = -lnv;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( pLine(tri.y_, tri.z_).lineGrainCheck(cntr, Rad, lnv, cp, ovrlp))
|
||||
{
|
||||
norm = -lnv;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( pLine(tri.z_, tri.x_).lineGrainCheck(cntr, Rad, lnv, cp, ovrlp))
|
||||
{
|
||||
norm = -lnv;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} // pFlow::grnTriInteraction
|
||||
|
||||
|
||||
#endif //__grainTriSurfaceContact_hpp__
|
107
src/Interaction/grainInteraction/grainInteraction/pLine.hpp
Normal file
107
src/Interaction/grainInteraction/grainInteraction/pLine.hpp
Normal file
@ -0,0 +1,107 @@
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __pLine_hpp__
|
||||
#define __pLine_hpp__
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
namespace pFlow::grnTriInteraction
|
||||
{
|
||||
|
||||
struct pLine
|
||||
{
|
||||
|
||||
realx3 p1_; // point 1
|
||||
realx3 p2_; // piont 2
|
||||
realx3 v_; // direction vector
|
||||
real L_; // line lenght
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
pLine(){}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
pLine(const realx3 &p1, const realx3 &p2)
|
||||
:
|
||||
p1_(p1),
|
||||
p2_(p2),
|
||||
v_(p2-p1),
|
||||
L_(length(v_))
|
||||
{}
|
||||
|
||||
// get a point on the line based on input 0<= t <= 1
|
||||
INLINE_FUNCTION_HD
|
||||
realx3 point(real t)const {
|
||||
return v_ * t + p1_;
|
||||
}
|
||||
|
||||
// return the projected point of point p on line
|
||||
INLINE_FUNCTION_HD
|
||||
realx3 projectPoint(const realx3 &p) const
|
||||
{
|
||||
return point(projectNormLength(p));
|
||||
}
|
||||
|
||||
// calculates the normalized distance between projected p and p1
|
||||
INLINE_FUNCTION_HD
|
||||
real projectNormLength(realx3 p) const
|
||||
{
|
||||
realx3 w = p - p1_;
|
||||
return dot(w,v_) / (L_*L_);
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
bool lineGrainCheck(
|
||||
const realx3 pos,
|
||||
real Rad,
|
||||
realx3 &nv,
|
||||
realx3 &cp,
|
||||
real &ovrlp)const
|
||||
{
|
||||
|
||||
|
||||
real t = projectNormLength(pos);
|
||||
|
||||
if(t >= 0.0 && t <= 1.0) cp = point(t);
|
||||
else if(t >= (-Rad / L_) && t < 0.0) cp = point(0.0);
|
||||
else if(t>1.0 && t >= (1.0 + Rad / L_)) cp = point(1.0);
|
||||
else return false;
|
||||
|
||||
realx3 vec = pos - cp; // from cp to pos
|
||||
|
||||
real dist = length(vec);
|
||||
ovrlp = Rad - dist;
|
||||
|
||||
if (ovrlp >= 0.0)
|
||||
{
|
||||
if (dist > 0)
|
||||
nv = vec / dist;
|
||||
else
|
||||
nv = v_;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} //pFlow::grnTriInteractio
|
||||
|
||||
#endif
|
108
src/Interaction/grainInteraction/grainInteraction/triWall.hpp
Normal file
108
src/Interaction/grainInteraction/grainInteraction/triWall.hpp
Normal file
@ -0,0 +1,108 @@
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __triWall_hpp__
|
||||
#define __triWall_hpp__
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
namespace pFlow::grnTriInteraction
|
||||
{
|
||||
|
||||
struct triWall
|
||||
{
|
||||
|
||||
realx3 n_;
|
||||
real offset_;
|
||||
|
||||
INLINE_FUNCTION_H
|
||||
triWall(const realx3& p1, const realx3& p2, const realx3& p3)
|
||||
{
|
||||
if(!makeWall(p1,p2,p3, n_, offset_))
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"bad input for the wall.\n";
|
||||
fatalExit;
|
||||
}
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
triWall(bool, const realx3& p1, const realx3& p2, const realx3& p3)
|
||||
{
|
||||
makeWall(p1,p2,p3,n_,offset_);
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
triWall(const realx3x3& tri)
|
||||
{
|
||||
makeWall(tri.x_, tri.y_, tri.z_, n_, offset_);
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
triWall(const triWall&) = default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
triWall& operator=(const triWall&) = default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
triWall(triWall&&) = default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
triWall& operator=(triWall&&) = default;
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
~triWall()=default;
|
||||
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
real normalDistFromWall(const realx3 &p) const
|
||||
{
|
||||
return dot(n_, p) + offset_;
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD
|
||||
realx3 nearestPointOnWall(const realx3 &p) const
|
||||
{
|
||||
real t = -(dot(n_, p) + offset_);
|
||||
return realx3(n_.x_*t + p.x_, n_.y_*t + p.y_, n_.z_*t + p.z_);
|
||||
}
|
||||
|
||||
INLINE_FUNCTION_HD static
|
||||
bool makeWall(
|
||||
const realx3& p1,
|
||||
const realx3& p2,
|
||||
const realx3& p3,
|
||||
realx3& n, real& offset)
|
||||
{
|
||||
n = cross(p2 - p1, p3 - p1);
|
||||
real len = length(n);
|
||||
|
||||
if (len < 0.00000000001) return false;
|
||||
n /= len;
|
||||
offset = -dot(n, p1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
68
src/Interaction/grainInteraction/grainInteractionsLinearModels.cpp
Executable file
68
src/Interaction/grainInteraction/grainInteractionsLinearModels.cpp
Executable file
@ -0,0 +1,68 @@
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include "grainInteraction.hpp"
|
||||
#include "geometryMotions.hpp"
|
||||
#include "grainContactForceModels.hpp"
|
||||
#include "unsortedContactList.hpp"
|
||||
#include "sortedContactList.hpp"
|
||||
#include "createBoundaryGrainInteraction.hpp"
|
||||
|
||||
|
||||
|
||||
#define createInteraction(ForceModel,GeomModel) \
|
||||
\
|
||||
template class pFlow::grainInteraction< \
|
||||
ForceModel, \
|
||||
GeomModel, \
|
||||
pFlow::unsortedContactList>; \
|
||||
\
|
||||
template class pFlow::grainInteraction< \
|
||||
ForceModel, \
|
||||
GeomModel, \
|
||||
pFlow::sortedContactList>; \
|
||||
createBoundaryGrainInteraction(ForceModel, GeomModel)
|
||||
|
||||
|
||||
createInteraction(pFlow::cfModels::grainRolling<pFlow::cfModels::cGAbsoluteLinear<true>>, pFlow::rotationAxisMotionGeometry);
|
||||
createInteraction(pFlow::cfModels::grainRolling<pFlow::cfModels::cGRelativeLinear<true>>, pFlow::rotationAxisMotionGeometry);
|
||||
|
||||
createInteraction(pFlow::cfModels::grainRolling<pFlow::cfModels::cGAbsoluteLinear<false>>, pFlow::rotationAxisMotionGeometry);
|
||||
createInteraction(pFlow::cfModels::grainRolling<pFlow::cfModels::cGRelativeLinear<false>>, pFlow::rotationAxisMotionGeometry);
|
||||
|
||||
|
||||
createInteraction(pFlow::cfModels::grainRolling<pFlow::cfModels::cGAbsoluteLinear<true>>, pFlow::stationaryGeometry);
|
||||
createInteraction(pFlow::cfModels::grainRolling<pFlow::cfModels::cGRelativeLinear<true>>, pFlow::stationaryGeometry);
|
||||
|
||||
createInteraction(pFlow::cfModels::grainRolling<pFlow::cfModels::cGAbsoluteLinear<false>>, pFlow::stationaryGeometry);
|
||||
createInteraction(pFlow::cfModels::grainRolling<pFlow::cfModels::cGRelativeLinear<false>>, pFlow::stationaryGeometry);
|
||||
|
||||
|
||||
createInteraction(pFlow::cfModels::grainRolling<pFlow::cfModels::cGAbsoluteLinear<true>>, pFlow::vibratingMotionGeometry);
|
||||
createInteraction(pFlow::cfModels::grainRolling<pFlow::cfModels::cGRelativeLinear<true>>, pFlow::vibratingMotionGeometry);
|
||||
|
||||
createInteraction(pFlow::cfModels::grainRolling<pFlow::cfModels::cGAbsoluteLinear<false>>, pFlow::vibratingMotionGeometry);
|
||||
createInteraction(pFlow::cfModels::grainRolling<pFlow::cfModels::cGRelativeLinear<false>>, pFlow::vibratingMotionGeometry);
|
||||
|
||||
createInteraction(pFlow::cfModels::grainRolling<pFlow::cfModels::cGAbsoluteLinear<true>>, pFlow::conveyorBeltMotionGeometry);
|
||||
createInteraction(pFlow::cfModels::grainRolling<pFlow::cfModels::cGRelativeLinear<true>>, pFlow::conveyorBeltMotionGeometry);
|
||||
|
||||
createInteraction(pFlow::cfModels::grainRolling<pFlow::cfModels::cGAbsoluteLinear<false>>, pFlow::conveyorBeltMotionGeometry);
|
||||
createInteraction(pFlow::cfModels::grainRolling<pFlow::cfModels::cGRelativeLinear<false>>, pFlow::conveyorBeltMotionGeometry);
|
43
src/Interaction/grainInteraction/grainInteractionsNonLinearModModels.cpp
Executable file
43
src/Interaction/grainInteraction/grainInteractionsNonLinearModModels.cpp
Executable file
@ -0,0 +1,43 @@
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include "grainInteraction.hpp"
|
||||
#include "geometryMotions.hpp"
|
||||
#include "grainContactForceModels.hpp"
|
||||
#include "unsortedContactList.hpp"
|
||||
#include "sortedContactList.hpp"
|
||||
#include "createBoundaryGrainInteraction.hpp"
|
||||
|
||||
|
||||
|
||||
#define createInteraction(ForceModel,GeomModel) \
|
||||
\
|
||||
template class pFlow::grainInteraction< \
|
||||
ForceModel, \
|
||||
GeomModel, \
|
||||
pFlow::unsortedContactList>; \
|
||||
\
|
||||
template class pFlow::grainInteraction< \
|
||||
ForceModel, \
|
||||
GeomModel, \
|
||||
pFlow::sortedContactList>; \
|
||||
createBoundaryGrainInteraction(ForceModel, GeomModel)
|
||||
|
||||
|
49
src/Interaction/grainInteraction/grainInteractionsNonLinearModels.cpp
Executable file
49
src/Interaction/grainInteraction/grainInteractionsNonLinearModels.cpp
Executable file
@ -0,0 +1,49 @@
|
||||
/*------------------------------- phasicFlow ---------------------------------
|
||||
O C enter of
|
||||
O O E ngineering and
|
||||
O O M ultiscale modeling of
|
||||
OOOOOOO F luid flow
|
||||
------------------------------------------------------------------------------
|
||||
Copyright (C): www.cemf.ir
|
||||
email: hamid.r.norouzi AT gmail.com
|
||||
------------------------------------------------------------------------------
|
||||
Licence:
|
||||
This file is part of phasicFlow code. It is a free software for simulating
|
||||
granular and multiphase flows. You can redistribute it and/or modify it under
|
||||
the terms of GNU General Public License v3 or any other later versions.
|
||||
|
||||
phasicFlow is distributed to help others in their research in the field of
|
||||
granular and multiphase flows, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#include "grainInteraction.hpp"
|
||||
#include "geometryMotions.hpp"
|
||||
#include "grainContactForceModels.hpp"
|
||||
#include "unsortedContactList.hpp"
|
||||
#include "sortedContactList.hpp"
|
||||
#include "createBoundaryGrainInteraction.hpp"
|
||||
|
||||
|
||||
|
||||
#define createInteraction(ForceModel,GeomModel) \
|
||||
\
|
||||
template class pFlow::grainInteraction< \
|
||||
ForceModel, \
|
||||
GeomModel, \
|
||||
pFlow::unsortedContactList>; \
|
||||
\
|
||||
template class pFlow::grainInteraction< \
|
||||
ForceModel, \
|
||||
GeomModel, \
|
||||
pFlow::sortedContactList>; \
|
||||
createBoundaryGrainInteraction(ForceModel, GeomModel)
|
||||
|
||||
|
||||
createInteraction(pFlow::cfModels::limitedCGNonLinearGrainRolling, pFlow::rotationAxisMotionGeometry);
|
||||
|
||||
createInteraction(pFlow::cfModels::nonLimitedCGNonLinearGrainRolling, pFlow::rotationAxisMotionGeometry);
|
||||
|
||||
createInteraction(pFlow::cfModels::limitedCGNonLinearGrainRolling, pFlow::stationaryGeometry);
|
||||
createInteraction(pFlow::cfModels::nonLimitedCGNonLinearGrainRolling, pFlow::stationaryGeometry);
|
@ -51,7 +51,7 @@ private:
|
||||
const geometry& geometry_;
|
||||
|
||||
static inline
|
||||
const message msg_ = message::ITEM_REARRANGE;
|
||||
const message msg_ = message::ITEMS_REARRANGE;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -110,7 +110,7 @@ public:
|
||||
return geometryMotion_;
|
||||
}
|
||||
|
||||
ContactListType& ppPairs()
|
||||
ContactListType& ppPairs()
|
||||
{
|
||||
return ppPairs_();
|
||||
}
|
||||
@ -148,7 +148,7 @@ public:
|
||||
const ContactForceModel& cfModel,
|
||||
uint32 step)
|
||||
{
|
||||
// for default boundary, no thing to be done
|
||||
// for default boundary, nothing to be done
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -156,20 +156,26 @@ public:
|
||||
|
||||
bool hearChanges
|
||||
(
|
||||
real t,
|
||||
real dt,
|
||||
uint32 iter,
|
||||
const timeInfo& ti,
|
||||
const message& msg,
|
||||
const anyList& varList
|
||||
) override
|
||||
{
|
||||
|
||||
if(msg.equivalentTo(message::BNDR_RESET))
|
||||
{
|
||||
// do nothing
|
||||
return true;
|
||||
}
|
||||
pOutput<<"Function (hearChanges in boundarySphereInteractions)is not implmented Message "<<
|
||||
msg <<endl<<" name "<< this->name() <<" type "<< this->type()<<endl;;
|
||||
//notImplementedFunction;
|
||||
msg <<endl<<" name "<< this->boundaryName() <<" type "<< this->type()<<endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isActive()const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static
|
||||
uniquePtr<BoundarySphereInteractionType> create(
|
||||
const boundaryBase& boundary,
|
||||
|
@ -7,11 +7,11 @@ pFlow::boundarySphereInteractionList<CFModel, gMModel>::boundarySphereInteractio
|
||||
const gMModel &geomMotion
|
||||
)
|
||||
:
|
||||
ListPtr<boundarySphereInteraction<CFModel,gMModel>>(6),
|
||||
boundaryListPtr<boundarySphereInteraction<CFModel,gMModel>>(),
|
||||
boundaries_(sphPrtcls.pStruct().boundaries())
|
||||
{
|
||||
//gSettings::sleepMiliSeconds(1000*pFlowProcessors().localRank());
|
||||
for(uint32 i=0; i<6; i++)
|
||||
output<<boundaries_.size()<<endl;
|
||||
ForAllBoundariesPtr(i, this)
|
||||
{
|
||||
this->set(
|
||||
i,
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
|
||||
#include "boundaryList.hpp"
|
||||
#include "ListPtr.hpp"
|
||||
#include "boundaryListPtr.hpp"
|
||||
#include "boundarySphereInteraction.hpp"
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ namespace pFlow
|
||||
template<typename contactForceModel,typename geometryMotionModel>
|
||||
class boundarySphereInteractionList
|
||||
:
|
||||
public ListPtr<boundarySphereInteraction<contactForceModel,geometryMotionModel>>
|
||||
public boundaryListPtr<boundarySphereInteraction<contactForceModel,geometryMotionModel>>
|
||||
{
|
||||
private:
|
||||
|
||||
|
@ -76,15 +76,17 @@ public:
|
||||
boundaryBase
|
||||
);
|
||||
|
||||
~periodicBoundarySphereInteraction()override = default;
|
||||
|
||||
|
||||
|
||||
~periodicBoundarySphereInteraction()override = default;
|
||||
|
||||
bool sphereSphereInteraction(
|
||||
real dt,
|
||||
const ContactForceModel& cfModel,
|
||||
uint32 step)override;
|
||||
|
||||
bool isActive()const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
@ -41,9 +41,9 @@ bool pFlow::sphereInteraction<cFM,gMM, cLT>::createSphereInteraction()
|
||||
geometryMotion_,
|
||||
timers());
|
||||
|
||||
ppContactList_ = makeUnique<ContactListType>(nPrtcl+1);
|
||||
ppContactList_ = makeUnique<ContactListType>("sphere-sphere",nPrtcl+1);
|
||||
|
||||
pwContactList_ = makeUnique<ContactListType>(nPrtcl/5+1);
|
||||
pwContactList_ = makeUnique<ContactListType>("sphere-wall",nPrtcl/5+1);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -134,18 +134,22 @@ pFlow::sphereInteraction<cFM,gMM, cLT>::sphereInteraction
|
||||
geometryMotion_(dynamic_cast<const GeometryMotionModel&>(geom)),
|
||||
sphParticles_(dynamic_cast<const sphereParticles&>(prtcl)),
|
||||
boundaryInteraction_(sphParticles_,geometryMotion_),
|
||||
ppInteractionTimer_("sphere-sphere interaction", &this->timers()),
|
||||
pwInteractionTimer_("sphere-wall interaction", &this->timers()),
|
||||
contactListMangementTimer_("contact-list management", &this->timers()),
|
||||
boundaryContactSearchTimer_("contact search for boundary", &this->timers()),
|
||||
boundaryInteractionTimer_("interaction for boundary", &this->timers()),
|
||||
contactListBoundaryTimer_("contact-list management for boundary", &this->timers())
|
||||
ppInteractionTimer_("sphere-sphere interaction (internal)", &this->timers()),
|
||||
pwInteractionTimer_("sphere-wall interaction (internal)", &this->timers()),
|
||||
boundaryInteractionTimer_("sphere-sphere interaction (boundary)",&this->timers()),
|
||||
contactListMangementTimer_("list management (interal)", &this->timers()),
|
||||
contactListMangementBoundaryTimer_("list management (boundary)", &this->timers())
|
||||
{
|
||||
|
||||
if(!createSphereInteraction())
|
||||
{
|
||||
fatalExit;
|
||||
}
|
||||
|
||||
for(uint32 i=0; i<6; i++)
|
||||
{
|
||||
activeBoundaries_[i] = boundaryInteraction_[i].ppPairsAllocated();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename cFM,typename gMM,template <class, class, class> class cLT>
|
||||
@ -158,45 +162,58 @@ template<typename cFM,typename gMM,template <class, class, class> class cLT>
|
||||
bool pFlow::sphereInteraction<cFM,gMM, cLT>::iterate()
|
||||
{
|
||||
|
||||
auto iter = this->currentIter();
|
||||
auto t = this->currentTime();
|
||||
auto dt = this->dt();
|
||||
timeInfo ti = this->TimeInfo();
|
||||
auto iter = ti.iter();
|
||||
auto t = ti.t();
|
||||
auto dt = ti.dt();
|
||||
|
||||
|
||||
bool broadSearch = contactSearch_().enterBroadSearch(iter, t, dt);
|
||||
auto& contactSearchRef = contactSearch_();
|
||||
|
||||
bool broadSearch = contactSearchRef.enterBroadSearch(ti);
|
||||
bool broadSearchBoundary = contactSearchRef.enterBroadSearchBoundary(ti);
|
||||
|
||||
/// update boundaries of the fields that are being used by inreaction
|
||||
sphParticles_.diameter().updateBoundaries(DataDirection::SlaveToMaster);
|
||||
sphParticles_.velocity().updateBoundaries(DataDirection::SlaveToMaster);
|
||||
sphParticles_.rVelocity().updateBoundaries(DataDirection::SlaveToMaster);
|
||||
sphParticles_.mass().updateBoundaries(DataDirection::SlaveToMaster);
|
||||
sphParticles_.I().updateBoundaries(DataDirection::SlaveToMaster);
|
||||
sphParticles_.propertyId().updateBoundaries(DataDirection::SlaveToMaster);
|
||||
|
||||
|
||||
/// lists
|
||||
if(broadSearch)
|
||||
{
|
||||
contactListMangementTimer_.start();
|
||||
ppContactList_().beforeBroadSearch();
|
||||
pwContactList_().beforeBroadSearch();
|
||||
ComputationTimer().start();
|
||||
ppContactList_().beforeBroadSearch();
|
||||
pwContactList_().beforeBroadSearch();
|
||||
ComputationTimer().end();
|
||||
contactListMangementTimer_.pause();
|
||||
}
|
||||
|
||||
contactListBoundaryTimer_.start();
|
||||
for(uint32 i=0; i<6u; i++)
|
||||
if(broadSearchBoundary)
|
||||
{
|
||||
auto& BI = boundaryInteraction_[i];
|
||||
if(BI.ppPairsAllocated()) BI.ppPairs().beforeBroadSearch();
|
||||
if(BI.pwPairsAllocated()) BI.pwPairs().beforeBroadSearch();
|
||||
contactListMangementBoundaryTimer_.start();
|
||||
ComputationTimer().start();
|
||||
|
||||
ForAllActiveBoundaries(i, boundaryInteraction_)
|
||||
//for(size_t i=0; i<6; i++)
|
||||
{
|
||||
if(activeBoundaries_[i])
|
||||
{
|
||||
auto& BI = boundaryInteraction_[i];
|
||||
BI.ppPairs().beforeBroadSearch();
|
||||
BI.pwPairs().beforeBroadSearch();
|
||||
}
|
||||
}
|
||||
|
||||
ComputationTimer().end();
|
||||
contactListMangementBoundaryTimer_.pause();
|
||||
}
|
||||
contactListBoundaryTimer_.pause();
|
||||
|
||||
if( sphParticles_.numActive()<=0)return true;
|
||||
|
||||
|
||||
if( !contactSearch_().broadSearch(
|
||||
iter,
|
||||
t,
|
||||
dt,
|
||||
ComputationTimer().start();
|
||||
if( !contactSearchRef.broadSearch(
|
||||
ti,
|
||||
ppContactList_(),
|
||||
pwContactList_()) )
|
||||
{
|
||||
@ -205,62 +222,69 @@ bool pFlow::sphereInteraction<cFM,gMM, cLT>::iterate()
|
||||
fatalExit;
|
||||
}
|
||||
|
||||
boundaryContactSearchTimer_.start();
|
||||
for(uint32 i=0; i<6u; i++)
|
||||
ForAllActiveBoundaries(i, boundaryInteraction_)
|
||||
//for(size_t i=0; i<6; i++)
|
||||
{
|
||||
auto& BI =boundaryInteraction_[i];
|
||||
if(BI.ppPairsAllocated())
|
||||
if(activeBoundaries_[i])
|
||||
{
|
||||
if( !contactSearch_().boundaryBroadSearch(
|
||||
auto& BI = boundaryInteraction_[i];
|
||||
if(!contactSearchRef.boundaryBroadSearch(
|
||||
i,
|
||||
iter,
|
||||
t,
|
||||
dt,
|
||||
ti,
|
||||
BI.ppPairs(),
|
||||
BI.pwPairs()))
|
||||
BI.pwPairs())
|
||||
)
|
||||
{
|
||||
fatalErrorInFunction<<
|
||||
"failed to perform broadSearch for boundary index "<<i<<endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
boundaryContactSearchTimer_.end();
|
||||
ComputationTimer().end();
|
||||
|
||||
if(broadSearch && contactSearch_().performedBroadSearch())
|
||||
if(broadSearch && contactSearchRef.performedSearch())
|
||||
{
|
||||
contactListMangementTimer_.resume();
|
||||
ppContactList_().afterBroadSearch();
|
||||
pwContactList_().afterBroadSearch();
|
||||
ComputationTimer().start();
|
||||
ppContactList_().afterBroadSearch();
|
||||
pwContactList_().afterBroadSearch();
|
||||
ComputationTimer().end();
|
||||
contactListMangementTimer_.end();
|
||||
}
|
||||
|
||||
contactListBoundaryTimer_.resume();
|
||||
for(uint32 i=0; i<6u; i++)
|
||||
if(broadSearchBoundary && contactSearchRef.performedSearchBoundary())
|
||||
{
|
||||
auto& BI = boundaryInteraction_[i];
|
||||
if(BI.ppPairsAllocated()) BI.ppPairs().afterBroadSearch();
|
||||
if(BI.pwPairsAllocated()) BI.pwPairs().afterBroadSearch();
|
||||
}
|
||||
contactListBoundaryTimer_.end();
|
||||
|
||||
|
||||
{
|
||||
boundaryInteractionTimer_.start();
|
||||
std::array<bool,6> requireStep{
|
||||
boundaryInteraction_[0].isBoundaryMaster(),
|
||||
boundaryInteraction_[1].isBoundaryMaster(),
|
||||
boundaryInteraction_[2].isBoundaryMaster(),
|
||||
boundaryInteraction_[3].isBoundaryMaster(),
|
||||
boundaryInteraction_[4].isBoundaryMaster(),
|
||||
boundaryInteraction_[5].isBoundaryMaster()};
|
||||
int step = 1;
|
||||
const auto& cfModel = this->forceModel_();
|
||||
while( std::any_of(requireStep.begin(), requireStep.end(), [](bool v) { return v==true; }))
|
||||
{
|
||||
for(uint32 i=0; i<6u; i++)
|
||||
contactListMangementBoundaryTimer_.resume();
|
||||
ComputationTimer().start();
|
||||
|
||||
ForAllActiveBoundaries(i, boundaryInteraction_)
|
||||
//for(size_t i=0; i<6; i++)
|
||||
{
|
||||
if(step==1u || requireStep[i] )
|
||||
if(activeBoundaries_[i])
|
||||
{
|
||||
auto& BI = boundaryInteraction_[i];
|
||||
BI.ppPairs().afterBroadSearch();
|
||||
BI.pwPairs().afterBroadSearch();
|
||||
}
|
||||
}
|
||||
|
||||
ComputationTimer().end();
|
||||
contactListMangementBoundaryTimer_.end();
|
||||
}
|
||||
|
||||
/// peform contact search on boundareis with active contact search (master boundaries)
|
||||
auto requireStep = boundariesMask<6>(true);
|
||||
const auto& cfModel = this->forceModel_();
|
||||
uint32 step=1;
|
||||
boundaryInteractionTimer_.start();
|
||||
ComputationTimer().start();
|
||||
while(requireStep.anyElement(true) && step <= 10)
|
||||
{
|
||||
ForAllBoundaries(i, boundaryInteraction_)
|
||||
//for(size_t i=0; i<6; i++)
|
||||
{
|
||||
if(requireStep[i] )
|
||||
{
|
||||
requireStep[i] = boundaryInteraction_[i].sphereSphereInteraction(
|
||||
dt,
|
||||
@ -271,44 +295,47 @@ bool pFlow::sphereInteraction<cFM,gMM, cLT>::iterate()
|
||||
}
|
||||
step++;
|
||||
}
|
||||
ComputationTimer().end();
|
||||
boundaryInteractionTimer_.pause();
|
||||
}
|
||||
|
||||
|
||||
ppInteractionTimer_.start();
|
||||
ComputationTimer().start();
|
||||
sphereSphereInteraction();
|
||||
ComputationTimer().end();
|
||||
ppInteractionTimer_.end();
|
||||
|
||||
|
||||
pwInteractionTimer_.start();
|
||||
ComputationTimer().start();
|
||||
sphereWallInteraction();
|
||||
ComputationTimer().start();
|
||||
pwInteractionTimer_.end();
|
||||
|
||||
{
|
||||
boundaryInteractionTimer_.resume();
|
||||
std::array<bool,6> requireStep{
|
||||
!boundaryInteraction_[0].isBoundaryMaster(),
|
||||
!boundaryInteraction_[1].isBoundaryMaster(),
|
||||
!boundaryInteraction_[2].isBoundaryMaster(),
|
||||
!boundaryInteraction_[3].isBoundaryMaster(),
|
||||
!boundaryInteraction_[4].isBoundaryMaster(),
|
||||
!boundaryInteraction_[5].isBoundaryMaster()};
|
||||
ComputationTimer().start();
|
||||
auto requireStep = boundariesMask<6>(true);
|
||||
|
||||
int step = 2;
|
||||
uint32 step = 11;
|
||||
const auto& cfModel = this->forceModel_();
|
||||
while(std::any_of(requireStep.begin(), requireStep.end(), [](bool v) { return v==true; }))
|
||||
while( requireStep.anyElement(true) && step < 20 )
|
||||
{
|
||||
for(uint32 i=0; i<6u; i++)
|
||||
ForAllBoundaries(i, boundaryInteraction_)
|
||||
//for(size_t i=0; i<6; i++)
|
||||
{
|
||||
if(requireStep[i])
|
||||
{
|
||||
requireStep[i] = boundaryInteraction_[i].sphereSphereInteraction(
|
||||
dt,
|
||||
this->forceModel_(),
|
||||
cfModel,
|
||||
step
|
||||
);
|
||||
}
|
||||
}
|
||||
step++;
|
||||
}
|
||||
ComputationTimer().end();
|
||||
boundaryInteractionTimer_.end();
|
||||
}
|
||||
|
||||
@ -324,17 +351,18 @@ bool pFlow::sphereInteraction<cFM,gMM, cLT>::afterIteration()
|
||||
template<typename cFM,typename gMM,template <class, class, class> class cLT>
|
||||
bool pFlow::sphereInteraction<cFM,gMM, cLT>::hearChanges
|
||||
(
|
||||
real t,
|
||||
real dt,
|
||||
uint32 iter,
|
||||
const timeInfo& ti,
|
||||
const message& msg,
|
||||
const anyList& varList
|
||||
)
|
||||
{
|
||||
if(msg.equivalentTo(message::ITEM_REARRANGE))
|
||||
if(msg.equivalentTo(message::ITEMS_REARRANGE))
|
||||
{
|
||||
notImplementedFunction;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
fatalErrorInFunction<<"Event "<< msg.eventNames()<<
|
||||
" is not handled in sphereInteraction"<<endl;
|
||||
return false;
|
||||
}
|
@ -25,6 +25,8 @@ Licence:
|
||||
#include "sphereParticles.hpp"
|
||||
#include "boundarySphereInteractionList.hpp"
|
||||
#include "sphereInteractionKernels.hpp"
|
||||
#include "boundariesMask.hpp"
|
||||
#include "MPITimer.hpp"
|
||||
//#include "unsortedContactList.hpp"
|
||||
|
||||
|
||||
@ -74,6 +76,9 @@ private:
|
||||
/// particle-particle and particle-wall interactions at boundaries
|
||||
BoundaryListType boundaryInteraction_;
|
||||
|
||||
/// a mask for active boundaries (boundaries with intreaction)
|
||||
boundariesMask<6> activeBoundaries_;
|
||||
|
||||
/// contact search object for pp and pw interactions
|
||||
uniquePtr<contactSearch> contactSearch_ = nullptr;
|
||||
|
||||
@ -93,14 +98,13 @@ private:
|
||||
/// timer for particle-wall interaction computations
|
||||
Timer pwInteractionTimer_;
|
||||
|
||||
/// timer for managing contact lists (only inernal points)
|
||||
Timer contactListMangementTimer_;
|
||||
|
||||
Timer boundaryContactSearchTimer_;
|
||||
/// timer for boundary interaction time
|
||||
Timer boundaryInteractionTimer_;
|
||||
|
||||
Timer contactListBoundaryTimer_;
|
||||
/// timer for managing contact lists (only inernal points)
|
||||
Timer contactListMangementTimer_;
|
||||
|
||||
Timer contactListMangementBoundaryTimer_;
|
||||
|
||||
|
||||
|
||||
@ -110,10 +114,6 @@ private:
|
||||
|
||||
bool sphereWallInteraction();
|
||||
|
||||
//bool managePPContactLists();
|
||||
|
||||
//bool managePWContactLists();
|
||||
|
||||
/// range policy for p-p interaction execution
|
||||
using rpPPInteraction =
|
||||
Kokkos::RangePolicy<Kokkos::IndexType<uint32>, Kokkos::Schedule<Kokkos::Dynamic>>;
|
||||
@ -152,9 +152,7 @@ public:
|
||||
|
||||
/// Check for changes in the point structures. (overriden from observer)
|
||||
bool hearChanges(
|
||||
real t,
|
||||
real dt,
|
||||
uint32 iter,
|
||||
const timeInfo& ti,
|
||||
const message& msg,
|
||||
const anyList& varList)override;
|
||||
|
||||
|
@ -53,6 +53,10 @@ createInteraction(pFlow::cfModels::nonLimitedLinearNormalRolling,pFlow::rotation
|
||||
createInteraction(pFlow::cfModels::limitedLinearNormalRolling, pFlow::vibratingMotionGeometry);
|
||||
createInteraction(pFlow::cfModels::nonLimitedLinearNormalRolling,pFlow::vibratingMotionGeometry);
|
||||
|
||||
// conveyorBeltGeometry
|
||||
createInteraction(pFlow::cfModels::limitedLinearNormalRolling, pFlow::conveyorBeltMotionGeometry);
|
||||
createInteraction(pFlow::cfModels::nonLimitedLinearNormalRolling,pFlow::conveyorBeltMotionGeometry);
|
||||
|
||||
// multiRotationAxisMotionGeometry
|
||||
//createInteraction(pFlow::cfModels::limitedLinearNormalRolling, pFlow::multiRotationAxisMotionGeometry);
|
||||
//createInteraction(pFlow::cfModels::nonLimitedLinearNormalRolling,pFlow::multiRotationAxisMotionGeometry);
|
||||
|
@ -53,6 +53,10 @@ createInteraction(pFlow::cfModels::nonLimitedNonLinearModNormalRolling,pFlow::ro
|
||||
createInteraction(pFlow::cfModels::limitedNonLinearModNormalRolling, pFlow::vibratingMotionGeometry);
|
||||
createInteraction(pFlow::cfModels::nonLimitedNonLinearModNormalRolling,pFlow::vibratingMotionGeometry);
|
||||
|
||||
// conveyorBeltMotionGeometry
|
||||
createInteraction(pFlow::cfModels::limitedNonLinearModNormalRolling, pFlow::conveyorBeltMotionGeometry);
|
||||
createInteraction(pFlow::cfModels::nonLimitedNonLinearModNormalRolling,pFlow::conveyorBeltMotionGeometry);
|
||||
|
||||
// multiRotationAxisMotionGeometry
|
||||
//createInteraction(pFlow::cfModels::limitedNonLinearModNormalRolling, pFlow::multiRotationAxisMotionGeometry);
|
||||
//createInteraction(pFlow::cfModels::nonLimitedNonLinearModNormalRolling,pFlow::multiRotationAxisMotionGeometry);
|
||||
createInteraction(pFlow::cfModels::limitedNonLinearModNormalRolling, pFlow::multiRotationAxisMotionGeometry);
|
||||
createInteraction(pFlow::cfModels::nonLimitedNonLinearModNormalRolling,pFlow::multiRotationAxisMotionGeometry);
|
||||
|
@ -53,6 +53,10 @@ createInteraction(pFlow::cfModels::nonLimitedNonLinearNormalRolling,pFlow::rotat
|
||||
createInteraction(pFlow::cfModels::limitedNonLinearNormalRolling, pFlow::vibratingMotionGeometry);
|
||||
createInteraction(pFlow::cfModels::nonLimitedNonLinearNormalRolling,pFlow::vibratingMotionGeometry);
|
||||
|
||||
// conveyorBeltMotionGeometry
|
||||
createInteraction(pFlow::cfModels::limitedNonLinearNormalRolling, pFlow::conveyorBeltMotionGeometry);
|
||||
createInteraction(pFlow::cfModels::nonLimitedNonLinearNormalRolling,pFlow::conveyorBeltMotionGeometry);
|
||||
|
||||
// multiRotationAxisMotionGeometry
|
||||
//createInteraction(pFlow::cfModels::limitedNonLinearNormalRolling, pFlow::multiRotationAxisMotionGeometry);
|
||||
//createInteraction(pFlow::cfModels::nonLimitedNonLinearNormalRolling,pFlow::multiRotationAxisMotionGeometry);
|
||||
|
Reference in New Issue
Block a user