OpenLB 1.8.1
Loading...
Searching...
No Matches
olb::particles::resolved Namespace Reference

Classes

struct  population_momentum_exchange
 
struct  population_momentum_exchange< T, 2, false >
 
struct  population_momentum_exchange< T, 2, true >
 
struct  population_momentum_exchange< T, 3, false >
 
struct  population_momentum_exchange< T, 3, true >
 

Functions

template<typename T , typename DESCRIPTOR , typename PARTICLETYPE >
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)
 
template<typename T , typename S , typename PARTICLETYPE >
PhysR< S, PARTICLETYPE::d > transformInput (Particle< T, PARTICLETYPE > &particle, const PhysR< S, PARTICLETYPE::d > &input)
 
template<typename T , typename S , typename PARTICLETYPE >
PhysR< S, PARTICLETYPE::d > transformDirection (Particle< T, PARTICLETYPE > &particle, const PhysR< S, PARTICLETYPE::d > &direction)
 
template<typename T , typename S , typename PARTICLETYPE >
bool isInsideCircumRadius (Particle< T, PARTICLETYPE > &particle, const PhysR< S, PARTICLETYPE::d > &input)
 
template<typename T , typename S , typename PARTICLETYPE >
bool isInsideParticle (Particle< T, PARTICLETYPE > &particle, const PhysR< S, PARTICLETYPE::d > &input)
 
template<typename T , typename S , typename PARTICLETYPE >
const S signedDistanceToParticle (Particle< T, PARTICLETYPE > &particle, const PhysR< S, PARTICLETYPE::d > &input)
 
template<typename T , typename S , typename PARTICLETYPE >
const S distanceToParticle (Particle< T, PARTICLETYPE > &particle, const Vector< S, PARTICLETYPE::d > &origin, const Vector< S, PARTICLETYPE::d > &direction, S precision, S pitch)
 
template<typename T , typename S , typename PARTICLETYPE >
const S distanceToParticle (Particle< T, PARTICLETYPE > &particle, const Vector< S, PARTICLETYPE::d > &origin, const Vector< S, PARTICLETYPE::d > &direction, S precision)
 
template<typename T , typename S , typename PARTICLETYPE >
Vector< S, PARTICLETYPE::d > normalOnParticleSurface (Particle< T, PARTICLETYPE > &particle, const Vector< S, PARTICLETYPE::d > &pos, const T meshSize)
 
template<typename T , typename S , typename PARTICLETYPE >
bool evalSolidVolumeFraction (T output[], const S input[], Particle< T, PARTICLETYPE > &particle)
 

Function Documentation

◆ distanceToParticle() [1/2]

template<typename T , typename S , typename PARTICLETYPE >
const S olb::particles::resolved::distanceToParticle ( Particle< T, PARTICLETYPE > & particle,
const Vector< S, PARTICLETYPE::d > & origin,
const Vector< S, PARTICLETYPE::d > & direction,
S precision )

Definition at line 175 of file smoothIndicatorInteraction.h.

179{
180 using namespace descriptors;
181 auto sIndicator = particle.template getField<SURFACE, SINDICATOR>();
182 PhysR<S, PARTICLETYPE::d> input = transformInput(particle, origin);
183 PhysR<S, PARTICLETYPE::d> dir = transformDirection(particle, direction);
184
185 T distance(T(0.));
186 if (util::distance(
187 distance, input, dir, precision,
188 [&](const Vector<T, PARTICLETYPE::d>& input) {
189 return sIndicator->signedDistance(input);
190 },
191 [&](const Vector<T, PARTICLETYPE::d>& pos) {
192 // bigger bounding box is usually necessary
193 return norm(pos) <= 1.5 * sIndicator->getCircumRadius();
194 })) {
195 return distance;
196 }
197 else {
198#ifdef OLB_DEBUG
199 OstreamManager clout(std::cout, "distanceCalculation");
200 clout << "WARNING: Distance to particle in direction "
201 << normalize(direction) << " couldn't be calculated." << std::endl;
202#endif
203 return T(0.);
204 }
205
206 __builtin_unreachable();
207}
PhysR< S, PARTICLETYPE::d > transformDirection(Particle< T, PARTICLETYPE > &particle, const PhysR< S, PARTICLETYPE::d > &direction)
PhysR< S, PARTICLETYPE::d > transformInput(Particle< T, PARTICLETYPE > &particle, const PhysR< S, PARTICLETYPE::d > &input)
constexpr T norm(const ScalarVector< T, D, IMPL > &a) any_platform
Euclidean vector norm.

References olb::util::distance(), olb::norm(), olb::normalize(), transformDirection(), and transformInput().

+ Here is the call graph for this function:

◆ distanceToParticle() [2/2]

template<typename T , typename S , typename PARTICLETYPE >
const S olb::particles::resolved::distanceToParticle ( Particle< T, PARTICLETYPE > & particle,
const Vector< S, PARTICLETYPE::d > & origin,
const Vector< S, PARTICLETYPE::d > & direction,
S precision,
S pitch )

Definition at line 138 of file smoothIndicatorInteraction.h.

142{
143 using namespace descriptors;
144 auto sIndicator = particle.template getField<SURFACE, SINDICATOR>();
145 PhysR<S, PARTICLETYPE::d> input = transformInput(particle, origin);
146 PhysR<S, PARTICLETYPE::d> dir = transformDirection(particle, direction);
147
148 T distance(T(0.));
149 if (util::distance(
150 distance, input, dir, precision, pitch,
151 [&](bool output[1], const T input[3]) {
152 output[0] = sIndicator->signedDistance(
153 PhysR<T, PARTICLETYPE::d>(input)) <= 0;
154 return output[0];
155 },
156 [&](const Vector<T, 3>& pos) {
157 // bigger bounding box is usually necessary
158 return norm(pos) <= 1.5 * sIndicator->getCircumRadius();
159 })) {
160 return distance;
161 }
162 else {
163#ifdef OLB_DEBUG
164 OstreamManager clout(std::cout, "distanceCalculation");
165 clout << "WARNING: Distance to particle in direction "
166 << normalize(direction) << " couldn't be calculated." << std::endl;
167#endif
168 return T(0.);
169 }
170
171 __builtin_unreachable();
172}

References olb::util::distance(), olb::norm(), olb::normalize(), transformDirection(), and transformInput().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ evalSolidVolumeFraction()

template<typename T , typename S , typename PARTICLETYPE >
bool olb::particles::resolved::evalSolidVolumeFraction ( T output[],
const S input[],
Particle< T, PARTICLETYPE > & particle )

Definition at line 225 of file smoothIndicatorInteraction.h.

227{
228 using namespace descriptors;
229 auto sIndicator = particle.template getField<SURFACE, SINDICATOR>();
230 T const signedDist =
232 return sdf::evalSolidVolumeFraction(output, signedDist,
233 sIndicator->getEpsilon());
234}
const S signedDistanceToParticle(Particle< T, PARTICLETYPE > &particle, const PhysR< S, PARTICLETYPE::d > &input)

References olb::sdf::evalSolidVolumeFraction(), and signedDistanceToParticle().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isInsideCircumRadius()

template<typename T , typename S , typename PARTICLETYPE >
bool olb::particles::resolved::isInsideCircumRadius ( Particle< T, PARTICLETYPE > & particle,
const PhysR< S, PARTICLETYPE::d > & input )

Definition at line 86 of file smoothIndicatorInteraction.h.

88{
89 using namespace descriptors;
90 auto sIndicator = access::getSmoothIndicatorPtr(particle);
91 return norm(access::getPosition(particle) - input) <=
92 sIndicator->getCircumRadius();
93}

References olb::particles::access::getPosition(), olb::particles::access::getSmoothIndicatorPtr(), and olb::norm().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isInsideParticle()

template<typename T , typename S , typename PARTICLETYPE >
bool olb::particles::resolved::isInsideParticle ( Particle< T, PARTICLETYPE > & particle,
const PhysR< S, PARTICLETYPE::d > & input )

Definition at line 96 of file smoothIndicatorInteraction.h.

98{
99 using namespace descriptors;
100 auto sIndicator = access::getSmoothIndicatorPtr(particle);
101
102 if (!isInsideCircumRadius(particle, input)) {
103 return false;
104 }
105
106 PhysR<S, PARTICLETYPE::d> newInput = transformInput(particle, input);
107 return sIndicator->signedDistance(newInput) <= 0;
108}
bool isInsideCircumRadius(Particle< T, PARTICLETYPE > &particle, const PhysR< S, PARTICLETYPE::d > &input)

References olb::particles::access::getSmoothIndicatorPtr(), isInsideCircumRadius(), and transformInput().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ momentumExchangeAtSurfaceLocation()

template<typename T , typename DESCRIPTOR , typename PARTICLETYPE >
bool olb::particles::resolved::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 )

Definition at line 76 of file momentumExchangeForce.h.

86{
87
88 using namespace descriptors;
89 constexpr unsigned D = DESCRIPTOR::d;
90 auto position = particles::access::getPosition(particle);
91
92 //Retrieve grid spacing
93 const T deltaR = blockGeometry.getDeltaR();
94 //Get inner phys position
95 T physRinner[D] = { };
96 Vector<T,D> physRV;
97 blockGeometry.getPhysR(physRV, latticeRinner);
98 for (unsigned iD = 0; iD < D; ++iD) {
99 physRinner[iD] = physRV[iD];
100 }
101 //Retrieve inner porosity
102 T porosityInner[1] = { };
103 particles::resolved::evalSolidVolumeFraction(porosityInner, physRinner, particle);
104 //Check whether particle and bulk is existent at location
105 if ( !util::nearZero(porosityInner[0]) && blockGeometry.get(latticeRinner)==bulkMaterial ) {
106 //Loop over distribution functions
107 for (int iPop = 1; iPop < DESCRIPTOR::q ; ++iPop) {
108 //Calculate outer lattice position (get next cell located in current direction)
109 const Vector<int,D> c = descriptors::c<DESCRIPTOR>(iPop);
110 const LatticeR<D> latticeRouter = latticeRinner + c;
111 //Retrieve outer phys position
112 T physRouter[D] = {0.};
113 Vector<T,D> physRouterV;
114 blockGeometry.getPhysR(physRouterV, latticeRouter);
115 for (unsigned iD = 0; iD < D; ++iD) {
116 physRouter[iD] = physRouterV[iD];
117 }
118 //Retrieve outer porosity
119 T porosityOuter[1] = {0.};
120 particles::resolved::evalSolidVolumeFraction(porosityOuter, physRouter, particle);
121 //if not both cells are in the full solid domain calculate force
122 if ( !(porosityInner[0]==1 && porosityOuter[0]==1) ) {
123 //Momentum Exchange Wen
124 const T f1 = blockLattice.get( latticeRouter )[iPop];
125 const T f2 = blockLattice.get( latticeRinner )[descriptors::opposite<DESCRIPTOR>(iPop)];
126 T pVel[D] = {0.};
127 for (unsigned iDim=0; iDim<D; ++iDim) {
128 pVel[iDim] = converter.getLatticeVelocity(particles::dynamics::calculateLocalVelocity(particle, PhysR<T,D>(physRinner))[iDim]);
129 momentumExchange[iDim] -= converter.getPhysForce(
130 population_momentum_exchange<T,D>::calculate( f1, f2, c[iDim], pVel[iDim], deltaR ) );
131 }
132
133 // Optional correction of the lubrication force
134 if constexpr (particles::access::providesIsInContact<PARTICLETYPE>()) {
135 auto contact = particle.template getField<NUMERICPROPERTIES,IS_IN_CONTACT>();
136
137 if (contact == 1) {
138 T vn = 0.0;
139 for (unsigned iDim=0; iDim<D; ++iDim) {
140 //std::cout << momentumExchange[iDim];
141 vn = vn + util::pow(momentumExchange[iDim],2);
142 }
143
144 vn = util::sqrt(vn);
145
146 auto cell = blockLattice.get(latticeRinner);
147 Vector<T,DESCRIPTOR::d> localLatticeFluidVelocity;
148 Vector<T,DESCRIPTOR::d> localPhysicalFluidVelocity;
149 cell.computeU(localLatticeFluidVelocity.data());
150
151 for(unsigned iD=0; iD<D; ++iD) {
152 localPhysicalFluidVelocity[iD] = converter.getPhysVelocity(localLatticeFluidVelocity[iD]);
153 }
154
155 T U = 0.0;
156 for (unsigned iDim=0; iDim<D; ++iDim) {
157 U = U + util::pow(pVel[iDim]-localLatticeFluidVelocity[iDim],2.0);
158 }
159 U = util::sqrt(U);
160
161
162 T deltaT = converter.getPhysDeltaT();
163 T deltaTLattice = converter.getLatticeTime(deltaT);
164 T rho_fluid = converter.getPhysDensity();
165
166 T factor = 1.0;
167
168 T maxForce = converter.getPhysForce(U * converter.getLatticeDensity(rho_fluid)/deltaTLattice)*factor;
169
170 if (util::fabs(vn) == 0){
171 vn = 0.5 * maxForce;
172 }
173 if (util::fabs(vn) > util::fabs(maxForce)) {
174 T mp = maxForce/vn;
175 for (unsigned iDim=0; iDim<D; ++iDim) {
176 //Set the force to the maximal force
177 momentumExchange[iDim] *= mp;
178 }
179 }
180 }
181 }
182 }
183
184 }
185 //Calculate lever (necessary for torque calculation)
186 lever = PhysR<T,D>(physRinner)-position;
187 return true;
188 }
189 else {
190 return false;
191 }
192}
Vector< T, D > getPhysR(LatticeR< D > latticeR) const
T getDeltaR() const
Read only access to the voxel size given in SI units (meter)
std::enable_if_t< sizeof...(L)==D, int > get(L... latticeR) const
Read-only access to a material number.
Cell< T, DESCRIPTOR > get(CellID iCell)
Get Cell interface for index iCell.
void computeU(T u[descriptors::d< DESCRIPTOR >()]) const
Compute fluid velocity on the cell.
Definition cell.hh:202
constexpr T getPhysDensity() const
return density in physical units
constexpr T getLatticeDensity(T physDensity) const
conversion from physical to lattice density
constexpr size_t getLatticeTime(T physTime) const
conversion from physical to lattice time
constexpr T getPhysVelocity(T latticeVelocity) const
conversion from lattice to physical velocity
constexpr T getLatticeVelocity(T physVelocity) const
conversion from physical to lattice velocity
constexpr T getPhysDeltaT() const
returns time spacing (timestep length) in s
constexpr T getPhysForce(T latticeForce) const
conversion from lattice to physical force

References olb::descriptors::c(), olb::particles::dynamics::calculateLocalVelocity(), olb::Vector< T, Size >::data(), evalSolidVolumeFraction(), olb::util::fabs(), olb::BlockGeometry< T, D >::get(), olb::BlockGeometry< T, D >::getDeltaR(), olb::UnitConverter< T, DESCRIPTOR >::getLatticeDensity(), olb::UnitConverter< T, DESCRIPTOR >::getLatticeTime(), olb::UnitConverter< T, DESCRIPTOR >::getLatticeVelocity(), olb::UnitConverter< T, DESCRIPTOR >::getPhysDeltaT(), olb::UnitConverter< T, DESCRIPTOR >::getPhysDensity(), olb::UnitConverter< T, DESCRIPTOR >::getPhysForce(), olb::BlockGeometry< T, D >::getPhysR(), olb::UnitConverter< T, DESCRIPTOR >::getPhysVelocity(), olb::particles::access::getPosition(), olb::util::nearZero(), olb::descriptors::opposite(), olb::util::pow(), olb::particles::access::providesIsInContact(), and olb::util::sqrt().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ normalOnParticleSurface()

template<typename T , typename S , typename PARTICLETYPE >
Vector< S, PARTICLETYPE::d > olb::particles::resolved::normalOnParticleSurface ( Particle< T, PARTICLETYPE > & particle,
const Vector< S, PARTICLETYPE::d > & pos,
const T meshSize )

Definition at line 211 of file smoothIndicatorInteraction.h.

213{
214 using namespace descriptors;
215 constexpr unsigned D = PARTICLETYPE::d;
216 auto sIndicator = particle.template getField<SURFACE, SINDICATOR>();
217
218 // the following gives us the option to overload the calculation of the surface normal for different indicators
219 return sIndicator->surfaceNormal(pos, meshSize, [&](const Vector<S, D>& pos) {
220 return transformInput(particle, pos);
221 });
222}

References transformInput().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ signedDistanceToParticle()

template<typename T , typename S , typename PARTICLETYPE >
const S olb::particles::resolved::signedDistanceToParticle ( Particle< T, PARTICLETYPE > & particle,
const PhysR< S, PARTICLETYPE::d > & input )

Definition at line 111 of file smoothIndicatorInteraction.h.

113{
114 using namespace descriptors;
115 auto sIndicator = particle.template getField<SURFACE, SINDICATOR>();
116 PhysR<S, PARTICLETYPE::d> newInput = transformInput(particle, input);
117
118 //Check whether elongation provided
119 if constexpr (access::providesElongation<PARTICLETYPE>()) {
120 const unsigned D = PARTICLETYPE::d;
121 //Retrieve original sdf
122 std::function<S(const Vector<S, D>&)> sdf =
123 [&sIndicator](const Vector<S, D>& input) {
124 return sIndicator->signedDistance(input);
125 };
126 //Retrieve elongation
127 auto elongation = access::getElongation(particle);
128 //Return elongated whapper
129 constexpr bool symmetryCheck = false; //User responsibility here.
130 return sdf::elongation<T, symmetryCheck>(sdf, newInput, elongation);
131 }
132 else {
133 return sIndicator->signedDistance(newInput);
134 }
135}

References olb::sdf::elongation(), olb::particles::access::getElongation(), olb::particles::access::providesElongation(), and transformInput().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ transformDirection()

template<typename T , typename S , typename PARTICLETYPE >
PhysR< S, PARTICLETYPE::d > olb::particles::resolved::transformDirection ( Particle< T, PARTICLETYPE > & particle,
const PhysR< S, PARTICLETYPE::d > & direction )

Definition at line 66 of file smoothIndicatorInteraction.h.

68{
69 constexpr unsigned D = PARTICLETYPE::d;
70 using namespace descriptors;
71
72 if constexpr (PARTICLETYPE::template providesNested<SURFACE, ROT_MATRIX>()) {
74 util::invertRotationMatrix<T, D>(
75 particle.template getField<SURFACE, ROT_MATRIX>());
76 return util::executeRotation<T, D>(direction, rotationMatrix);
77 }
78 else {
79 return direction;
80 }
81
82 __builtin_unreachable();
83}

References olb::util::executeRotation(), and olb::util::invertRotationMatrix().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ transformInput()

template<typename T , typename S , typename PARTICLETYPE >
PhysR< S, PARTICLETYPE::d > olb::particles::resolved::transformInput ( Particle< T, PARTICLETYPE > & particle,
const PhysR< S, PARTICLETYPE::d > & input )

Definition at line 44 of file smoothIndicatorInteraction.h.

46{
47 using namespace descriptors;
48 constexpr unsigned D = PARTICLETYPE::d;
49
50 const PhysR<T, D> position = particle.template getField<GENERAL, POSITION>();
51 if constexpr (PARTICLETYPE::template providesNested<SURFACE, ROT_MATRIX>()) {
53 util::invertRotationMatrix<T, D>(
54 particle.template getField<SURFACE, ROT_MATRIX>());
55 return util::executeRotation<T, D, true>(input, rotationMatrix, position);
56 }
57 else {
58 return input - position;
59 }
60
61 __builtin_unreachable();
62}

References olb::util::executeRotation(), and olb::util::invertRotationMatrix().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: