25#ifndef LATTICE_MOMENTUM_EXCHANGE_FORCE_HH
26#define LATTICE_MOMENTUM_EXCHANGE_FORCE_HH
34template <
typename T,
typename DESCRIPTOR,
typename PARTICLETYPE,
typename BLOCKFUNCTOR>
41 const std::unordered_set<int>& ignoredMaterials,
const F f )
43 (DESCRIPTOR::d+utilities::dimensions::convert<DESCRIPTOR::d>::rotation+1)*(particleSystem.size()-iP0))
45 constexpr unsigned D = DESCRIPTOR::d;
47 this->getName() =
"physParticleForce";
48 int maxC = this->_sLattice.getLoadBalancer().size();
49 this->_blockF.reserve(maxC);
50 const PhysR<T,D> min = particles::communication::getCuboidMin<T,D>(
52 const PhysR<T,D> max = particles::communication::getCuboidMax<T,D>(
55 for (
int iC = 0; iC < maxC; ++iC) {
56 this->_blockF.emplace_back(
new BLOCKFUNCTOR(
57 this->_sLattice.getBlock(iC),
59 particleSystem, converter, min, max,
60 periodic, iP0, ignoredMaterials, f));
64template <
typename T,
typename DESCRIPTOR,
typename PARTICLETYPE,
typename BLOCKFUNCTOR>
68 for (
int iS=0; iS<this->getTargetDim(); ++iS) {
71 for (
int iC = 0; iC < this->_sLattice.getLoadBalancer().size(); ++iC) {
72 this->getBlockF(iC)(output, &input[1]);
75#ifdef PARALLEL_MODE_MPI
76 for (
int iS = 0; iS < this->getTargetDim(); ++iS) {
85template<
typename T,
typename DESCRIPTOR,
typename PARTICLETYPE>
93 const std::unordered_set<int>& ignoredMaterials,
const F f )
95 (DESCRIPTOR::d+utilities::dimensions::convert<DESCRIPTOR::d>::rotation+1)*(particleSystem.size()-iP0)),
96 _blockGeometry(blockGeometry), _blockLattice(blockLattice),
97 _particleSystem(particleSystem),
98 _cellMin(cellMin), _cellMax(cellMax), _periodic(periodic),
99 _iP0(iP0), _ignoredMaterials(ignoredMaterials), _f(f)
101 this->getName() =
"physMomentumExchangeForce";
104template<
typename T,
typename DESCRIPTOR,
typename PARTICLETYPE>
107 constexpr unsigned D = DESCRIPTOR::d;
109 constexpr int serialSize = D+Drot+1;
111 using namespace descriptors;
117 constexpr int padding = 0;
118 const std::size_t iPeval = iP - _iP0;
120 _blockLattice, padding, position, circumRadius,
123 if (_ignoredMaterials.find(_blockGeometry.getMaterial(latticeRinner)) == _ignoredMaterials.end()) {
124 Vector<T,D>tmpForce(0.);
125 PhysR<T,D> lever(0.);
126 if ( particles::resolved::momentumExchangeAtSurfaceLocation(tmpForce.data(),
127 lever, latticeRinner, this->_blockGeometry,
128 this->_blockLattice, this->_converter, particle) ){
134 if constexpr ( PARTICLETYPE::template providesNested<SURFACE,COR_OFFSET>() ){
135 lever -= Vector<T,D> ( particle.template getField<SURFACE,COR_OFFSET>() );
139 const Vector<T,Drot> torque = particles::dynamics::torque_from_force<D,T>::calculate( tmpForce, lever );
142 this->_blockGeometry.getPhysR(physR, latticeRinner);
143 _f(particle, physR, tmpForce, torque);
146 for (unsigned iDim=0; iDim<D; ++iDim) {
147 output[iDim+iPeval*serialSize] += tmpForce[iDim];
149 for (unsigned iRot=0; iRot<Drot; ++iRot) {
150 output[(iRot+D)+iPeval*serialSize] += torque[iRot];
156 output[D+Drot+iPeval*serialSize] += numVoxels;
159template<
typename T,
typename DESCRIPTOR,
typename PARTICLETYPE>
162 constexpr unsigned D = DESCRIPTOR::d;
164 using namespace descriptors;
167 bool anyPeriodic =
false;
168 for (
unsigned iDim=0; iDim<D; ++iDim) {
169 anyPeriodic = anyPeriodic || _periodic[iDim];
173 for (std::size_t iP=_iP0; iP!=_particleSystem.size(); ++iP) {
174 auto particle = _particleSystem.get(iP);
175 if (particles::access::isValid(particle)){
178 const T circumRadius = particles::access::getRadius(particle);
179 const PhysR<T,D> position = particles::access::getPosition(particle);
181 bool surfaceOutOfGeometry =
false;
183 particles::checkSmoothIndicatorOutOfGeometry(surfaceOutOfGeometry, ghostPos,
184 _cellMin, _cellMax, position, circumRadius, _periodic);
186 if (!surfaceOutOfGeometry) {
187 evaluate(output, particle, iP);
191 particle.template setField<GENERAL,POSITION>(ghostPos);
192 evaluate(output, particle, iP);
194 particle.template setField<GENERAL,POSITION>(position);
195 evaluate(output, particle, iP);
199 evaluate(output, particle, iP);
211template<
typename T,
typename DESCRIPTOR,
typename PARTICLETYPE,
bool useTorque>
218 useTorque ? utilities::dimensions::convert<DESCRIPTOR::d>::rotation : DESCRIPTOR::d)
220 this->getName() =
"localMomentumExchange";
221 int maxC = this->_sLattice.getLoadBalancer().size();
222 this->_blockF.reserve(maxC);
223 for (
int iC = 0; iC < maxC; ++iC) {
225 this->_sLattice.getBlock(iC),
232template<
typename T,
typename DESCRIPTOR,
typename PARTICLETYPE,
bool useTorque>
239 useTorque ? utilities::dimensions::convert<DESCRIPTOR::d>::rotation : DESCRIPTOR::d)
241 this->getName() =
"localMomentumExchange";
242 int maxC = this->_sLattice.getLoadBalancer().size();
243 this->_blockF.reserve(maxC);
244 for (
int iC = 0; iC < maxC; ++iC) {
247 auto& particleSystem = *bParticleSystems[iC];
250 this->_sLattice.getBlock(iC),
258template <
typename T,
typename DESCRIPTOR,
typename PARTICLETYPE,
bool useTorque>
265 useTorque ? utilities::dimensions::convert<DESCRIPTOR::d>::rotation : DESCRIPTOR::d),
266 _blockLattice(blockLattice),
267 _blockGeometry(blockGeometry),
268 _particleSystem(particleSystem)
270 this->getName() =
"localMomentumExchange";
273template <
typename T,
typename DESCRIPTOR,
typename PARTICLETYPE,
bool useTorque>
276 using namespace descriptors;
277 const unsigned D = DESCRIPTOR::d;
280 for (
unsigned iDim=0; iDim<D; ++iDim) {
286 for (std::size_t iP=_iP0; iP!=_particleSystem.size(); ++iP) {
287 auto particle = _particleSystem.get(iP);
288 auto circumRadius = particle.template getField<SURFACE,SINDICATOR>()->getCircumRadius();
289 auto position = particle.template getField<GENERAL,POSITION>();
293 position, circumRadius) ){
298 lever, input, this->_blockGeometry,
299 this->_blockLattice, this->_converter, particle) ){
302 if constexpr ( PARTICLETYPE::template providesNested<SURFACE,COR_OFFSET>() ){
303 lever -=
Vector<T,D> ( particle.template getField<SURFACE,COR_OFFSET>() );
310 if constexpr(!useTorque){
311 for (
unsigned iDim=0; iDim<D; ++iDim) {
312 output[iDim] = tmpForce[iDim];
315 for (
unsigned iRot=0; iRot<Drot; ++iRot) {
316 output[iRot] = torque[iRot];
Representation of a block geometry.
functor to get pointwise momentum exchange on local lattice (block level)
bool operator()(T output[], const int input[]) override
BlockLatticeMomentumExchangeForceLocal(BlockLattice< T, DESCRIPTOR > &blockLattice, const BlockGeometry< T, DESCRIPTOR::d > &blockGeometry, particles::ParticleSystem< T, PARTICLETYPE > &particleSystem, const UnitConverter< T, DESCRIPTOR > &converter)
Functor that returns forces acting on a particle surface, returns data in output for every particle i...
void evaluate(T output[], particles::Particle< T, PARTICLETYPE > &particle, int iP)
BlockLatticeMomentumExchangeForce(BlockLattice< T, DESCRIPTOR > &blockLattice, const BlockGeometry< T, DESCRIPTOR::d > &blockGeometry, particles::ParticleSystem< T, PARTICLETYPE > &particleSystem, const UnitConverter< T, DESCRIPTOR > &converter, PhysR< T, DESCRIPTOR::d > cellMin=PhysR< T, DESCRIPTOR::d >(0.), PhysR< T, DESCRIPTOR::d > cellMax=PhysR< T, DESCRIPTOR::d >(0.), Vector< bool, DESCRIPTOR::d > periodic=Vector< bool, DESCRIPTOR::d >(false), std::size_t iP0=0, const std::unordered_set< int > &ignoredMaterials=std::unordered_set< int >{}, const F f=[](auto &, const auto &, const auto &, const auto &){})
Platform-abstracted block lattice for external access and inter-block interaction.
Representation of a statistic for a parallel 2D geometry.
BlockGeometry< T, D > & getBlockGeometry(int locIC)
Read and write access to a single block geometry.
SuperLatticeMomentumExchangeForceLocalParallel(SuperLattice< T, DESCRIPTOR > &sLattice, const UnitConverter< T, DESCRIPTOR > &converter, const SuperGeometry< T, DESCRIPTOR::d > &superGeometry, particles::SuperParticleSystem< T, PARTICLETYPE > &sParticleSystem)
The following are functors that work in the traditional (output[], input[]) sense,...
bool operator()(T output[], const int input[]) override
SuperLatticeParticleForce(SuperLattice< T, DESCRIPTOR > &sLattice, const SuperGeometry< T, DESCRIPTOR::d > &superGeometry, particles::ParticleSystem< T, PARTICLETYPE > &particleSystem, const UnitConverter< T, DESCRIPTOR > &converter, Vector< bool, DESCRIPTOR::d > periodic=Vector< bool, DESCRIPTOR::d >(false), std::size_t iP0=0, const std::unordered_set< int > &ignoredMaterials=std::unordered_set< int >{}, const F f=[](auto &, const auto &, const auto &, const auto &){})
Super class maintaining block lattices for a cuboid decomposition.
CuboidGeometry< T, D > & getCuboidGeometry()
Read and write access to cuboid geometry.
Conversion between physical and lattice units, as well as discretization.
constexpr const T * data() const any_platform
std::vector< ParticleSystem< T, PARTICLETYPE > * > & getBlockParticleSystems()
void reduceAndBcast(T &reductVal, MPI_Op op, int root=0, MPI_Comm comm=MPI_COMM_WORLD)
Reduction operation, followed by a broadcast.
T getRadius(Particle< T, PARTICLETYPE > &particle)
Vector< T, PARTICLETYPE::d > getPosition(Particle< T, PARTICLETYPE > particle)
bool momentumExchangeAtSurfaceLocation(T momentumExchange[], PhysR< T, DESCRIPTOR::d > &lever, const LatticeR< DESCRIPTOR::d > &latticeRinner, const BlockGeometry< T, DESCRIPTOR::d > &blockGeometry, BlockLattice< T, DESCRIPTOR > &blockLattice, const UnitConverter< T, DESCRIPTOR > &converter, Particle< T, PARTICLETYPE > &particle, const int bulkMaterial=1)
bool getBlockParticleIntersection(const BlockGeometry< T, D > &blockGeometry, T invDeltaX, LatticeR< D > &start, LatticeR< D > &end, Vector< T, D > position, T circumRadius)
void forSpatialLocationsInBlockParticleIntersection(const BlockGeometry< T, DESCRIPTOR::d > &blockGeometry, BlockLattice< T, DESCRIPTOR > &blockLattice, Vector< T, DESCRIPTOR::d > position, T circumRadius, F f)
Top level namespace for all of OpenLB.
std::conditional_t< DESCRIPTOR::d==2, BlockLatticePhysF2D< T, DESCRIPTOR >, BlockLatticePhysF3D< T, DESCRIPTOR > > BlockLatticePhysF
std::conditional_t< DESCRIPTOR::d==2, SuperLatticePhysF2D< T, DESCRIPTOR >, SuperLatticePhysF3D< T, DESCRIPTOR > > SuperLatticePhysF
static constexpr Vector< T, utilities::dimensions::convert< D >::rotation > calculate(Vector< T, D > force, PhysR< T, D > lever)
Converts dimensions by deriving from given cartesian dimension D.