OpenLB 1.8.1
Loading...
Searching...
No Matches
olb::FreeSurfaceInterfaceReconstructionPostProcessor2D< T, DESCRIPTOR > Class Template Reference

Free Surface Processor 2-3 Interface Reconstruction Replaces incoming DFs by calculating equilibrium functions and using the laplace pressure to include surface tension. More...

#include <freeSurfacePostProcessor2D.h>

+ Collaboration diagram for olb::FreeSurfaceInterfaceReconstructionPostProcessor2D< T, DESCRIPTOR >:

Public Types

using parameters
 

Public Member Functions

int getPriority () const
 
template<typename CELL , typename PARAMETERS >
void apply (CELL &cell, PARAMETERS &params) any_platform
 Free Surface Processor 2-3: Interface Reconstruction.
 

Static Public Attributes

static constexpr OperatorScope scope = OperatorScope::PerCellWithParameters
 

Detailed Description

template<typename T, typename DESCRIPTOR>
class olb::FreeSurfaceInterfaceReconstructionPostProcessor2D< T, DESCRIPTOR >

Free Surface Processor 2-3 Interface Reconstruction Replaces incoming DFs by calculating equilibrium functions and using the laplace pressure to include surface tension.

Marks cells which may be changed at the last step.

Definition at line 63 of file freeSurfacePostProcessor2D.h.

Member Typedef Documentation

◆ parameters

template<typename T , typename DESCRIPTOR >
using olb::FreeSurfaceInterfaceReconstructionPostProcessor2D< T, DESCRIPTOR >::parameters
Initial value:
meta::list<
FreeSurface::DROP_ISOLATED_CELLS,
FreeSurface::TRANSITION,
FreeSurface::LONELY_THRESHOLD,
FreeSurface::HAS_SURFACE_TENSION,
FreeSurface::SURFACE_TENSION_PARAMETER
>

Definition at line 65 of file freeSurfacePostProcessor2D.h.

Member Function Documentation

◆ apply()

template<typename T , typename DESCRIPTOR >
template<typename CELL , typename PARAMETERS >
void olb::FreeSurfaceInterfaceReconstructionPostProcessor2D< T, DESCRIPTOR >::apply ( CELL & cell,
PARAMETERS & params )

Free Surface Processor 2-3: Interface Reconstruction.

Definition at line 146 of file freeSurfacePostProcessor2D.hh.

146 {
147
148 using namespace olb::FreeSurface;
149
150 const bool drop_isolated_cells = params.template get<FreeSurface::DROP_ISOLATED_CELLS>();
151 const auto transition = params.template get<FreeSurface::TRANSITION>();
152 const auto lonely_threshold = params.template get<FreeSurface::LONELY_THRESHOLD>();
153 const bool has_surface_tension = params.template get<FreeSurface::HAS_SURFACE_TENSION>();
154 const auto surface_tension = params.template get<FreeSurface::SURFACE_TENSION_PARAMETER>();
155
157 return;
158 }
159
161
162 // Adjust gas density, using Laplace pressure but without support for the bubble model
163 T deltaRho = T(0);
164 if (has_surface_tension && nbrInfo.has_gas_neighbours) {
165 const T curvature = computeCurvature(cell);
166 deltaRho = T(6) * surface_tension * curvature;
167 }
168 const T bubble_density = T(1);
169 const T gas_density = bubble_density - deltaRho;
170
171 // Replace the distribution functions of the gas cell using the updated density.
172 // A race condition is not expected here since only the distribution functions
173 // of an interface cell are modified, while only the distribution functions of
174 // a neighboring gas cell are read.
176 for (int iPop = 1; iPop < DESCRIPTOR::q; iPop++) {
177 auto nbrCell = cell.neighbor(descriptors::c<DESCRIPTOR>(iPop));
178
179 // Distribution functions of an interface cell are reconstructed only for the missing directions,
180 // i.e., incoming DFs from gas cells, using the pressure anti bounce back boundary condition.
181 // Note: the notation used here differs from that in N. Thuerey's dissertation (2007), refer to the
182 // explanation given above.
183 if (isCellType(nbrCell, FreeSurface::Type::Gas)) {
184 constexpr bool usePrecise = true;
185 Vector<T, DESCRIPTOR::d> prev_velocity = cell.template getField<FreeSurface::PREVIOUS_VELOCITY>();
186
187 // (1) Precise formulation of the pressure anti bounce back boundary condition: feq_(i) + feq_(-i) - nbr(i)
188 // This is mathematically identical to the regular formulation, but the linear term of the 2nd order
189 // equilibrium equation is manually eliminated due to its cancellation during summation, i.e., c_(-i).u = -(c_(i).u).
190 // This formulation offers consistent floating-point rounding behaviour during arithmetic operations.
191 if constexpr (usePrecise) {
192 const T uSqr = util::normSqr<T, DESCRIPTOR::d>(prev_velocity);
193 Vector<T, DESCRIPTOR::d> direction{};
194 for (int i = 0; i < DESCRIPTOR::d; ++i) { direction[i] = descriptors::c<DESCRIPTOR>(iPop, i); }
195 const T c_u = util::dotProduct(direction, prev_velocity);
196
198 T(2) * gas_density * descriptors::t<T, DESCRIPTOR>(iPop) * (T(1) + T(4.5) * c_u * c_u - T(1.5) * uSqr)
199 - T(2) * descriptors::t<T, DESCRIPTOR>(iPop)
200 - nbrCell[iPop];
201 }
202 // (2) Regular formulation of the pressure anti bounce back boundary condition: feq_(i) + feq_(-i) - nbr(i)
203 // This formulation might suffer from inconsistent floating-point rounding behaviour during arithmetic
204 // operations, where the expression c_(-i).u = -(c_(i).u) could become untrue.
205 else {
206 T u[DESCRIPTOR::d] = {prev_velocity[0], prev_velocity[1]};
208 equilibrium<DESCRIPTOR>::secondOrder(iPop, gas_density, u)
210 - nbrCell[iPop];
211 }
212 }
213 else {
216 }
217 }
218
219 // Update interafce cell populations using the computed dfs in previous step.
220 for (int iPop = 1; iPop < DESCRIPTOR::q; iPop++) { cell[iPop] = dfs[iPop]; }
221
222 // Using the updated mass and density, find and set appropriate flag on the current interface cell
223 const auto rho = cell.computeRho();
224 const auto mass = cell.template getField<FreeSurface::MASS>();
225
226 // An interface cell is flagged as toGas if its volume fraction is below the threshold
227 if (mass < -transition * rho) {
229 return;
230 }
231
232 // An interface cell is flagged as toFluid if its volume fraction is above the (1.0 + threshold)
233 if (mass > (T(1) + transition) * rho) {
235 return;
236 }
237
238 // An interface cell with no fluid neighbours is flagged as toGas:
239 // (1) If its volume fraction is below the (lonely threshold) and has interface neighbours (not isolated)
240 // (2) If it has no interface neighbours (isolated) and drop_isolated_cells is set
241 if (!nbrInfo.has_fluid_neighbours) {
242 if (mass < lonely_threshold * rho && nbrInfo.interface_neighbours != 0) {
244 return;
245 }
246
247 if (nbrInfo.interface_neighbours == 0 && drop_isolated_cells) {
249 return;
250 }
251 }
252
253 // An interface cell with no gas neighbours is flagged as toFluid:
254 // (1) If its volume fraction is above the (1.0 - lonely threshold) and has interface neighbours (not isolated)
255 // (2) If it has no interface neighbours (isolated) and drop_isolated_cells is set
256 if (!nbrInfo.has_gas_neighbours) {
257 if (mass > (T(1) - lonely_threshold) * rho && nbrInfo.interface_neighbours != 0) {
259 return;
260 }
261
262 if (nbrInfo.interface_neighbours == 0 && drop_isolated_cells) {
264 return;
265 }
266 }
267}
Plain old scalar vector.
bool isCellType(CELL &cell, const FreeSurface::Type &type)
V computeCurvature(CELL &cell)
void setCellFlags(CELL &cell, const FreeSurface::Flags &flags)
NeighbourInfo getNeighbourInfo(CELL &cell)
constexpr T t(unsigned iPop, tag::CUM) any_platform
Definition cum.h:108
constexpr int c(unsigned iPop, unsigned iDim) any_platform
Definition functions.h:83
constexpr int opposite(unsigned iPop) any_platform
Definition functions.h:95
auto normSqr(const ARRAY_LIKE &u) any_platform
Compute norm square of a d-dimensional vector.
Definition util.h:145
T dotProduct(const Vector< T, D > &a, const Vector< T, D > &b)
dot product
static V secondOrder(int iPop, const RHO &rho, const U &u, const USQR &uSqr) any_platform
Computation of equilibrium distribution, second order in u.
Definition lbm.h:51

References olb::descriptors::c(), olb::util::dotProduct(), olb::FreeSurface::Gas, olb::FreeSurface::NeighbourInfo::has_fluid_neighbours, olb::FreeSurface::NeighbourInfo::has_gas_neighbours, olb::FreeSurface::Interface, olb::FreeSurface::NeighbourInfo::interface_neighbours, olb::util::normSqr(), olb::descriptors::opposite(), olb::equilibrium< DESCRIPTOR >::secondOrder(), olb::descriptors::t(), olb::FreeSurface::ToFluid, and olb::FreeSurface::ToGas.

+ Here is the call graph for this function:

◆ getPriority()

template<typename T , typename DESCRIPTOR >
int olb::FreeSurfaceInterfaceReconstructionPostProcessor2D< T, DESCRIPTOR >::getPriority ( ) const
inline

Definition at line 75 of file freeSurfacePostProcessor2D.h.

75 {
76 return 2;
77 }

Member Data Documentation

◆ scope

template<typename T , typename DESCRIPTOR >
OperatorScope olb::FreeSurfaceInterfaceReconstructionPostProcessor2D< T, DESCRIPTOR >::scope = OperatorScope::PerCellWithParameters
staticconstexpr

Definition at line 73 of file freeSurfacePostProcessor2D.h.


The documentation for this class was generated from the following files: