MPI-boundaries for processor

This commit is contained in:
Hamidreza Norouzi 2024-04-27 08:55:00 -07:00
parent 94fcc3d01b
commit 5f90605a41
10 changed files with 993 additions and 0 deletions

View 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.
-----------------------------------------------------------------------------*/
#include "processorBoundaryContactSearch.hpp"
#include "contactSearch.hpp"
#include "particles.hpp"
//#include "pointStructure.hpp"
//#include "geometry.hpp"
void pFlow::processorBoundaryContactSearch::setSearchBox()
{
auto l = boundary().neighborLength();
auto n = boundary().boundaryPlane().normal();
auto pp1 = boundary().boundaryPlane().parallelPlane(l);
auto pp2 = boundary().boundaryPlane().parallelPlane(-l);
realx3 minP1 = min(min(min(pp1.p1(), pp1.p2()), pp1.p3()), pp1.p4());
realx3 maxP1 = max(max(max(pp1.p1(), pp1.p2()), pp1.p3()), pp1.p4());
realx3 minP2 = min(min(min(pp2.p1(), pp2.p2()), pp2.p3()), pp2.p4());
realx3 maxP2 = max(max(max(pp2.p1(), pp2.p2()), pp2.p3()), pp2.p4());
auto minP = min(minP1, minP2) - l*(realx3(1.0)-abs(n));
auto maxP = max(maxP1, maxP2) + l*(realx3(1.0)-abs(n));
searchBox_={minP, maxP};
}
pFlow::processorBoundaryContactSearch::processorBoundaryContactSearch(
const dictionary &dict,
const boundaryBase &boundary,
const contactSearch &cSearch)
:
boundaryContactSearch(dict, boundary, cSearch),
diameter_(cSearch.Particles().boundingSphere()),
masterSearch_(this->isBoundaryMaster())
{
if(masterSearch_)
{
setSearchBox();
real minD;
real maxD;
cSearch.Particles().boundingSphereMinMax(minD, maxD);
ppContactSearch_ = makeUnique<twoPartContactSearch>(
searchBox_,
maxD);
}
else
{
searchBox_={{0,0,0},{0,0,0}};
}
}
bool pFlow::processorBoundaryContactSearch::broadSearch
(
uint32 iter,
real t,
real dt,
csPairContainerType &ppPairs,
csPairContainerType &pwPairs,
bool force
)
{
if(masterSearch_)
{
/*const auto thisPoints = boundary().thisPoints();
const auto& neighborProcPoints = boundary().neighborProcPoints();
const auto& bDiams = diameter_.BoundaryField(thisBoundaryIndex());
const auto thisDiams = bDiams.thisField();
const auto& neighborProcDiams = bDiams.neighborProcField();
ppContactSearch_().broadSearchPP(
ppPairs,
thisPoints,
thisDiams,
neighborProcPoints,
neighborProcDiams);
pOutput<<"ppPairs size in boundary"<< ppPairs.size()<<endl; */
return true;
}else
{
return true;
}
}

View File

@ -0,0 +1,74 @@
/*------------------------------- 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 __processorBoundaryContactSearch_hpp__
#define __processorBoundaryContactSearch_hpp__
#include "boundaryContactSearch.hpp"
#include "pointFields.hpp"
#include "twoPartContactSearch.hpp"
namespace pFlow
{
class processorBoundaryContactSearch : public boundaryContactSearch
{
private:
box searchBox_;
uniquePtr<twoPartContactSearch> ppContactSearch_ = nullptr;
const realPointField_D& diameter_;
bool masterSearch_;
void setSearchBox();
public:
TypeInfo("boundaryContactSearch<MPI,processor>")
processorBoundaryContactSearch(
const dictionary& dict,
const boundaryBase& boundary,
const contactSearch& cSearch
);
~processorBoundaryContactSearch() override = default;
add_vCtor(
boundaryContactSearch,
processorBoundaryContactSearch,
boundaryBase
);
bool broadSearch(
uint32 iter,
real t,
real dt,
csPairContainerType& ppPairs,
csPairContainerType& pwPairs,
bool force = false
) override;
};
}
#endif //__processorBoundaryContactSearch_hpp__

View File

@ -0,0 +1,160 @@
#include "twoPartContactSearch.hpp"
#include "twoPartContactSearchKernels.hpp"
#include "phasicFlowKokkos.hpp"
#include "streams.hpp"
void pFlow::twoPartContactSearch::checkAllocateNext(uint32 n)
{
if( nextCapacity_ < n)
{
nextCapacity_ = n;
reallocNoInit(next_, n);
}
}
void pFlow::twoPartContactSearch::nullifyHead()
{
fill(head_, static_cast<uint32>(-1));
}
void pFlow::twoPartContactSearch::nullifyNext(uint32 n)
{
fill(next_, 0u, n, static_cast<uint32>(-1));
}
void pFlow::twoPartContactSearch::buildList(
const deviceScatteredFieldAccess<realx3> &points)
{
if(points.empty())return;
uint32 n = points.size();
checkAllocateNext(n);
nullifyNext(n);
nullifyHead();
pFlow::twoPartContactSearchKernels::buildNextHead(
points,
searchCells_,
head_,
next_
);
}
pFlow::twoPartContactSearch::twoPartContactSearch
(
const box &domain,
real cellSize,
real sizeRatio
)
:
searchCells_(domain, cellSize),
head_("periodic:head",searchCells_.nx(), searchCells_.ny(), searchCells_.nz()),
sizeRatio_(sizeRatio)
{
}
bool pFlow::twoPartContactSearch::broadSearchPP
(
csPairContainerType &ppPairs,
const deviceScatteredFieldAccess<realx3> &points1,
const deviceScatteredFieldAccess<real>& diams1,
const deviceScatteredFieldAccess<realx3> &points2,
const deviceScatteredFieldAccess<real>& diams2,
const realx3& transferVec
)
{
buildList(points1);
uint32 nNotInserted = 1;
// loop until the container size fits the numebr of contact pairs
while (nNotInserted > 0)
{
nNotInserted = pFlow::twoPartContactSearchKernels::broadSearchPP
(
ppPairs,
points1,
diams1,
points2,
diams2,
transferVec,
head_,
next_,
searchCells_,
sizeRatio_
);
if(nNotInserted)
{
// - resize the container
// note that getFull now shows the number of failed insertions.
uint32 len = max(nNotInserted,100u) ;
auto oldCap = ppPairs.capacity();
ppPairs.increaseCapacityBy(len);
INFORMATION<< "Particle-particle contact pair container capacity increased from "<<
oldCap << " to "<<ppPairs.capacity()<<" in peiodicBoundaryContactSearch."<<END_INFO;
}
}
return true;
}
bool pFlow::twoPartContactSearch::broadSearchPP
(
csPairContainerType &ppPairs,
const deviceScatteredFieldAccess<realx3> &points1,
const deviceScatteredFieldAccess<real> &diams1,
const realx3Vector_D& points2,
const realVector_D& diams2
)
{
buildList(points1);
uint32 nNotInserted = 1;
// loop until the container size fits the numebr of contact pairs
while (nNotInserted > 0)
{
nNotInserted = pFlow::twoPartContactSearchKernels::broadSearchPP
(
ppPairs,
points1,
diams1,
points2,
diams2,
head_,
next_,
searchCells_,
sizeRatio_
);
if(nNotInserted)
{
// - resize the container
// note that getFull now shows the number of failed insertions.
uint32 len = max(nNotInserted,100u) ;
auto oldCap = ppPairs.capacity();
ppPairs.increaseCapacityBy(len);
INFORMATION<< "Particle-particle contact pair container capacity increased from "<<
oldCap << " to "<<ppPairs.capacity()<<" in peiodicBoundaryContactSearch."<<END_INFO;
}
}
return true;
}

View File

@ -0,0 +1,103 @@
/*------------------------------- 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 __twoPartContactSearch_hpp__
#define __twoPartContactSearch_hpp__
#include "contactSearchGlobals.hpp"
#include "scatteredFieldAccess.hpp"
#include "cells.hpp"
#include "VectorSingles.hpp"
namespace pFlow
{
class twoPartContactSearch
{
public:
using HeadType = deviceViewType3D<uint32>;
using NextType = deviceViewType1D<uint32>;
private:
cells searchCells_;
HeadType head_{ "periodic::head", 1, 1, 1 };
NextType next_{ "periodic::next", 1 };
real sizeRatio_ = 1.0;
uint32 nextCapacity_ = 0;
void checkAllocateNext(uint32 n);
void nullifyHead();
void nullifyNext(uint32 n);
void buildList(
const deviceScatteredFieldAccess<realx3> &points);
public:
twoPartContactSearch(
const box &domain,
real cellSize,
real sizeRatio = 1.0);
/// @brief Perform a broad-search for spheres in two adjacent regions.
/// Region 1 is considered as the master (primary) region and region 2 as slave
/// @param ppPairs pairs container which holds i and j
/// @param points1 point positions in region 1
/// @param diams1 diameter of spheres in region 1
/// @param points2 point positions in region 2
/// @param diams2 diameter of spheres in region 2
/// @param transferVec a vector to transfer points from region 2 to region 1
/// @return true if it is successful
bool broadSearchPP(
csPairContainerType &ppPairs,
const deviceScatteredFieldAccess<realx3> &points1,
const deviceScatteredFieldAccess<real> &diams1,
const deviceScatteredFieldAccess<realx3> &points2,
const deviceScatteredFieldAccess<real> &diams2,
const realx3 &transferVec);
bool broadSearchPP(
csPairContainerType &ppPairs,
const deviceScatteredFieldAccess<realx3> &points1,
const deviceScatteredFieldAccess<real> &diams1,
const realx3Vector_D& points2,
const realVector_D& diams2);
const auto& searchCells()const
{
return searchCells_;
}
real sizeRatio()const
{
return sizeRatio_;
}
};
}
#endif //__twoPartContactSearch_hpp__

View File

@ -0,0 +1,188 @@
#include "twoPartContactSearchKernels.hpp"
INLINE_FUNCTION_HD
bool
sphereSphereCheckB(
const pFlow::realx3& p1,
const pFlow::realx3 p2,
pFlow::real d1,
pFlow::real d2
)
{
return pFlow::length(p2 - p1) < 0.5 * (d2 + d1);
}
void
pFlow::twoPartContactSearchKernels::buildNextHead(
const deviceScatteredFieldAccess<realx3>& points,
const cells& searchCells,
deviceViewType3D<uint32>& head,
deviceViewType1D<uint32>& next
)
{
if (points.empty())
return;
uint32 n = points.size();
Kokkos::parallel_for(
"pFlow::ppwBndryContactSearch::buildList",
deviceRPolicyStatic(0, n),
LAMBDA_HD(uint32 i) {
int32x3 ind;
if (searchCells.pointIndexInDomain(points[i], ind))
{
// discards points out of searchCell
uint32 old =
Kokkos::atomic_exchange(&head(ind.x(), ind.y(), ind.z()), i);
next[i] = old;
}
}
);
Kokkos::fence();
}
pFlow::uint32
pFlow::twoPartContactSearchKernels::broadSearchPP(
csPairContainerType& ppPairs,
const deviceScatteredFieldAccess<realx3>& points,
const deviceScatteredFieldAccess<real>& diams,
const deviceScatteredFieldAccess<realx3>& mirrorPoints,
const deviceScatteredFieldAccess<real>& mirrorDiams,
const realx3& transferVec,
const deviceViewType3D<uint32>& head,
const deviceViewType1D<uint32>& next,
const cells& searchCells,
const real sizeRatio
)
{
if (points.empty())
return 0;
if (mirrorPoints.empty())
return 0;
auto nMirror = mirrorPoints.size();
uint32 getFull = 0;
Kokkos::parallel_reduce(
"pFlow::twoPartContactSearchKernels::broadSearchPP",
deviceRPolicyStatic(0, nMirror),
LAMBDA_HD(const uint32 mrrI, uint32& getFullUpdate) {
realx3 p_m = mirrorPoints(mrrI) + transferVec;
int32x3 ind_m;
if (!searchCells.pointIndexInDomain(p_m, ind_m))
return;
real d_m = sizeRatio * mirrorDiams[mrrI];
for (int ii = -1; ii < 2; ii++)
{
for (int jj = -1; jj < 2; jj++)
{
for (int kk = -1; kk < 2; kk++)
{
auto ind = ind_m + int32x3{ ii, jj, kk };
if (!searchCells.inCellRange(ind))
continue;
uint32 thisI = head(ind.x(), ind.y(), ind.z());
while (thisI != -1)
{
auto d_n = sizeRatio * diams[thisI];
// first item is for this boundary and second itme,
// for mirror
if(sphereSphereCheckB(p_m, points[thisI], d_m, d_n)&&
ppPairs.insert(thisI,mrrI) == -1)
{
getFullUpdate++;
}
thisI = next(thisI);
}
}
}
}
},
getFull
);
return getFull;
}
pFlow::uint32
pFlow::twoPartContactSearchKernels::broadSearchPP(
csPairContainerType& ppPairs,
const deviceScatteredFieldAccess<realx3>& points1,
const deviceScatteredFieldAccess<real>& diams1,
const realx3Vector_D& points2,
const realVector_D& diams2,
const deviceViewType3D<uint32>& head,
const deviceViewType1D<uint32>& next,
const cells& searchCells,
real sizeRatio
)
{
if (points1.empty())
return 0;
if (points2.empty())
return 0;
auto nP2 = points2.size();
auto points2View = points2.deviceView();
auto diams2View = diams2.deviceView();
uint32 getFull = 0;
Kokkos::parallel_reduce(
"pFlow::twoPartContactSearchKernels::broadSearchPP",
deviceRPolicyStatic(0, nP2),
LAMBDA_HD(const uint32 i2, uint32& getFullUpdate) {
realx3 p_m = points2View(i2);
int32x3 ind_m;
if (!searchCells.pointIndexInDomain(p_m, ind_m))
return;
real d_m = sizeRatio * diams2View[i2];
for (int ii = -1; ii < 2; ii++)
{
for (int jj = -1; jj < 2; jj++)
{
for (int kk = -1; kk < 2; kk++)
{
auto ind = ind_m + int32x3{ ii, jj, kk };
if (!searchCells.inCellRange(ind))
{
continue;
}
uint32 i1 = head(ind.x(), ind.y(), ind.z());
while (i1 != -1)
{
auto d_n = sizeRatio * diams1[i1];
// first item is for this boundary and second itme,
// for mirror
if(sphereSphereCheckB(p_m, points1[i1], d_m, d_n)&&
ppPairs.insert(i1,i2) == -1)
{
getFullUpdate++;
}
i1 = next(i1);
}
}
}
}
},
getFull
);
return getFull;
}

View File

@ -0,0 +1,49 @@
#ifndef __twoPartContactSearchKernels_hpp__
#define __twoPartContactSearchKernels_hpp__
#include "contactSearchGlobals.hpp"
#include "cells.hpp"
#include "contactSearchFunctions.hpp"
#include "scatteredFieldAccess.hpp"
#include "VectorSingles.hpp"
namespace pFlow::twoPartContactSearchKernels
{
void buildNextHead(
const deviceScatteredFieldAccess<realx3> &points,
const cells &searchCells,
deviceViewType3D<uint32> &head,
deviceViewType1D<uint32> &next );
uint32 broadSearchPP
(
csPairContainerType &ppPairs,
const deviceScatteredFieldAccess<realx3> &points,
const deviceScatteredFieldAccess<real> &diams,
const deviceScatteredFieldAccess<realx3> &mirrorPoints,
const deviceScatteredFieldAccess<real> &mirrorDiams,
const realx3 &transferVec,
const deviceViewType3D<uint32> &head,
const deviceViewType1D<uint32> &next,
const cells &searchCells,
real sizeRatio
);
uint32
broadSearchPP(
csPairContainerType& ppPairs,
const deviceScatteredFieldAccess<realx3>& points1,
const deviceScatteredFieldAccess<real>& diams1,
const realx3Vector_D& points2,
const realVector_D& diams2,
const deviceViewType3D<uint32>& head,
const deviceViewType1D<uint32>& next,
const cells& searchCells,
real sizeRatio
);
}
#endif //__twoPartContactSearchKernels_hpp__

View File

@ -0,0 +1,131 @@
#ifndef __processorBoundarySIKernels_hpp__
#define __processorBoundarySIKernels_hpp__
namespace pFlow::MPI::processorBoundarySIKernels
{
template<typename ContactListType, typename ContactForceModel>
inline
void sphereSphereInteraction
(
real dt,
const ContactListType& cntctList,
const ContactForceModel& forceModel,
const deviceScatteredFieldAccess<realx3>& thisPoints,
const deviceViewType1D<real>& thisDiam,
const deviceViewType1D<uint32>& thisPropId,
const deviceViewType1D<realx3>& thisVel,
const deviceViewType1D<realx3>& thisRVel,
const deviceViewType1D<realx3>& thisCForce,
const deviceViewType1D<realx3>& thisCTorque,
const deviceViewType1D<realx3>& neighborPoints,
const deviceViewType1D<real>& neighborDiam,
const deviceViewType1D<uint32>& neighborPropId,
const deviceViewType1D<realx3>& neighborVel,
const deviceViewType1D<realx3>& neighborRVel,
const deviceViewType1D<realx3>& neighborCForce,
const deviceViewType1D<realx3>& neighborCTorque
)
{
using ValueType = typename ContactListType::ValueType;
uint32 ss = cntctList.size();
if(ss == 0u)return;
uint32 lastItem = cntctList.loopCount();
Kokkos::parallel_for(
"pFlow::MPI::processorBoundarySIKernels::sphereSphereInteraction",
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 = j;
real Ri = 0.5*thisDiam[ind_i];
real Rj = 0.5*neighborDiam[ind_j];
realx3 xi = thisPoints.field()[ind_i];
realx3 xj = neighborPoints[ind_j];
real dist = length(xj-xi);
real ovrlp = (Ri+Rj) - dist;
if( ovrlp >0.0 )
{
auto Nij = (xj-xi)/max(dist,smallValue);
auto wi = thisRVel[ind_i];
auto wj = neighborRVel[ind_j];
auto Vr = thisVel[ind_i] - neighborVel[ind_j] + cross((Ri*wi+Rj*wj), Nij);
auto history = cntctList.getValue(n);
int32 propId_i = thisPropId[ind_i];
int32 propId_j = neighborPropId[ind_j];
realx3 FCn, FCt, Mri, Mrj, Mij, Mji;
// calculates contact force
forceModel.contactForce(
dt, i, j,
propId_i, propId_j,
Ri, Rj,
ovrlp,
Vr, Nij,
history,
FCn, FCt);
forceModel.rollingFriction(
dt, i, j,
propId_i, propId_j,
Ri, Rj,
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(&thisCForce[ind_i].x_,FC.x_);
Kokkos::atomic_add(&thisCForce[ind_i].y_,FC.y_);
Kokkos::atomic_add(&thisCForce[ind_i].z_,FC.z_);
Kokkos::atomic_add(&neighborCForce[ind_j].x_,-FC.x_);
Kokkos::atomic_add(&neighborCForce[ind_j].y_,-FC.y_);
Kokkos::atomic_add(&neighborCForce[ind_j].z_,-FC.z_);
Kokkos::atomic_add(&thisCTorque[ind_i].x_, Mij.x_);
Kokkos::atomic_add(&thisCTorque[ind_i].y_, Mij.y_);
Kokkos::atomic_add(&thisCTorque[ind_i].z_, Mij.z_);
Kokkos::atomic_add(&neighborCTorque[ind_j].x_, Mji.x_);
Kokkos::atomic_add(&neighborCTorque[ind_j].y_, Mji.y_);
Kokkos::atomic_add(&neighborCTorque[ind_j].z_, Mji.z_);
cntctList.setValue(n,history);
}
else
{
cntctList.setValue(n, ValueType());
}
});
Kokkos::fence();
}
} //pFlow::MPI::processorBoundarySIKernels
#endif //__processorBoundarySIKernels_hpp__

View File

@ -0,0 +1,73 @@
/*------------------------------- 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 "processorBoundarySIKernels.hpp"
template <typename cFM, typename gMM>
pFlow::MPI::processorBoundarySphereInteraction<cFM, gMM>::processorBoundarySphereInteraction(
const boundaryBase &boundary,
const sphereParticles &sphPrtcls,
const GeometryMotionModel &geomMotion)
:
boundarySphereInteraction<cFM,gMM>(
boundary,
sphPrtcls,
geomMotion
),
masterInteraction_(boundary.isBoundaryMaster())
{
pOutput<<"Processor boundayrCondition for "<< boundary.name()<<endl;
}
template <typename cFM, typename gMM>
bool pFlow::MPI::processorBoundarySphereInteraction<cFM, gMM>::sphereSphereInteraction
(
real dt,
const ContactForceModel &cfModel
)
{
if(!masterInteraction_) return true;
const auto & sphPar = this->sphParticles();
uint32 thisIndex = this->boundary().thisBoundaryIndex();
const auto& a = sphPar.diameter().BoundaryField(thisIndex).neighborProcField().deviceViewAll();
/*pFlow::MPI::processorBoundarySIKernels::sphereSphereInteraction(
dt,
this->ppPairs(),
cfModel,
this->boundary().thisPoints(),
sphPar.diameter().deviceViewAll(),
sphPar.propertyId().deviceViewAll(),
sphPar.velocity().deviceViewAll(),
sphPar.rVelocity().deviceViewAll(),
sphPar.contactForce().deviceViewAll(),
sphPar.contactTorque().deviceViewAll(),
this->boundary().neighborProcPoints().deviceViewAll(),
sphPar.diameter().BoundaryField(thisIndex).neighborProcField().deviceViewAll(),
sphPar.propertyId().BoundaryField(thisIndex).neighborProcField().deviceViewAll(),
sphPar.velocity().BoundaryField(thisIndex).neighborProcField().deviceViewAll(),
sphPar.rVelocity().BoundaryField(thisIndex).neighborProcField().deviceViewAll(),
sphPar.contactForce().BoundaryField(thisIndex).neighborProcField().deviceViewAll(),
sphPar.contactTorque().BoundaryField(thisIndex).neighborProcField().deviceViewAll()
);*/
return true;
}

View File

@ -0,0 +1,90 @@
/*------------------------------- 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 __processorBoundarySphereInteraction_hpp__
#define __processorBoundarySphereInteraction_hpp__
#include "boundarySphereInteraction.hpp"
namespace pFlow::MPI
{
template<typename contactForceModel,typename geometryMotionModel>
class processorBoundarySphereInteraction
:
public boundarySphereInteraction<contactForceModel, geometryMotionModel>
{
public:
using PBSInteractionType =
processorBoundarySphereInteraction<contactForceModel,geometryMotionModel>;
using BSInteractionType =
boundarySphereInteraction<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:
bool masterInteraction_;
public:
TypeInfoTemplate22("boundarySphereInteraction", "processor",ContactForceModel, MotionModel);
processorBoundarySphereInteraction(
const boundaryBase& boundary,
const sphereParticles& sphPrtcls,
const GeometryMotionModel& geomMotion
);
add_vCtor
(
BSInteractionType,
PBSInteractionType,
boundaryBase
);
~processorBoundarySphereInteraction()override = default;
bool sphereSphereInteraction(
real dt,
const ContactForceModel& cfModel)override;
};
}
#include "processorBoundarySphereInteraction.cpp"
#endif //__processorBoundarySphereInteraction_hpp__

View File

@ -0,0 +1,17 @@
#include "processorBoundarySphereInteraction.hpp"
#include "geometryMotions.hpp"
#include "contactForceModels.hpp"
template class pFlow::MPI::processorBoundarySphereInteraction
<
pFlow::cfModels::limitedNonLinearNormalRolling,
pFlow::rotationAxisMotionGeometry
>;
template class pFlow::MPI::processorBoundarySphereInteraction
<
pFlow::cfModels::nonLimitedNonLinearNormalRolling,
pFlow::rotationAxisMotionGeometry
>;