OpenLB 1.7
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Public Attributes | List of all members
olb::FreeSurfaceMassFlowPostProcessor3D< T, DESCRIPTOR > Class Template Reference

Free Surface Processor 1-3 Mass Flow Cleans up leftover flags from the previous simulation step. More...

#include <freeSurfacePostProcessor3D.h>

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

Public Types

using parameters
 

Public Member Functions

int getPriority () const
 
template<typename CELL , typename PARAMETERS >
void apply (CELL &cell, PARAMETERS &parameters) any_platform
 

Static Public Attributes

static constexpr OperatorScope scope = OperatorScope::PerCellWithParameters
 

Detailed Description

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

Free Surface Processor 1-3 Mass Flow Cleans up leftover flags from the previous simulation step.

This post processor is responsible for the calculation of exchange mass with the help of the distribution functions. 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. This whole step should be included in the collideAndStream step, though heavy modification of openlb would be necessary

Definition at line 43 of file freeSurfacePostProcessor3D.h.

Member Typedef Documentation

◆ parameters

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

Definition at line 45 of file freeSurfacePostProcessor3D.h.

Member Function Documentation

◆ apply()

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

Definition at line 55 of file freeSurfacePostProcessor3D.hh.

55 {
56
57 using namespace olb::FreeSurface;
58
59 const bool drop_isolated_cells = vars.template get<FreeSurface::DROP_ISOLATED_CELLS>();
60 const T transition = vars.template get<FreeSurface::TRANSITION>();
61 const T lonely_threshold = vars.template get<FreeSurface::LONELY_THRESHOLD>();
62 const bool has_surface_tension = vars.template get<FreeSurface::HAS_SURFACE_TENSION>();
63 const T surface_tension_parameter = vars.template get<FreeSurface::SURFACE_TENSION_PARAMETER>();
64 //const T force_conversion_factor = vars.template get<FreeSurface::FORCE_CONVERSION_FACTOR>();
65 //const T lattice_size = vars.template get<FreeSurface::LATTICE_SIZE>();
66
67 /*
68 * Minor "hack". Remove all cell flags here, because it is needed in the last processor due to pulling steps in processor 6 and 7
69 */
70 setCellFlags(cell, static_cast<FreeSurface::Flags>(0));
71
72 /*
73 * This processor only works on interface types
74 */
76 T mass_tmp = cell.template getField<FreeSurface::MASS>();
77
78 FreeSurface::NeighbourInfo neighbour_info = getNeighbourInfo(cell);
79
80 for (int iPop = 1; iPop < DESCRIPTOR::q; ++iPop){
81 auto cellC = cell.neighbor({descriptors::c<DESCRIPTOR>(iPop, 0),
82 descriptors::c<DESCRIPTOR>(iPop, 1),
83 descriptors::c<DESCRIPTOR>(iPop, 2)});
84 int iPop_op = descriptors::opposite<DESCRIPTOR>(iPop);
85
86 /*
87 * Iterate over neighbours and perform a mass exchange. Interface to fluid are simple cases.
88 * Interface to interface has to be symmetric and multiple cases are for artifact reduction
89 * from Thuerey
90 * Added a distinction between the amount of interface nodes. Weight consideration seems to cause artifacts.
91 */
93 mass_tmp += cell[iPop_op] - cellC[iPop];
94 } else if ( isCellType(cellC, FreeSurface::Type::Interface)) {
95 FreeSurface::NeighbourInfo neighbour_neighbour_info = getNeighbourInfo(cellC);
96
97 T mass_flow = 0.;
98
99 if( !neighbour_info.has_fluid_neighbours){
100 if(!neighbour_neighbour_info.has_fluid_neighbours){
101 if(neighbour_info.interface_neighbours < neighbour_neighbour_info.interface_neighbours){
102 mass_flow = -cellC[iPop];// - descriptors::t<T,DESCRIPTOR>(iPop);
103 }else if(neighbour_info.interface_neighbours > neighbour_neighbour_info.interface_neighbours){
104 mass_flow = cell[iPop_op];// + descriptors::t<T,DESCRIPTOR>(iPop_op);
105 }else{
106 mass_flow = cell[iPop_op] - cellC[iPop];
107 }
108 }else {
109 mass_flow = -cellC[iPop];// - descriptors::t<T,DESCRIPTOR>(iPop);
110 }
111 }else if(!neighbour_info.has_gas_neighbours){
112 if(!neighbour_neighbour_info.has_gas_neighbours){
113 if(neighbour_info.interface_neighbours < neighbour_neighbour_info.interface_neighbours){
114 mass_flow = cell[iPop_op];// + descriptors::t<T,DESCRIPTOR>(iPop_op);
115 }else if(neighbour_info.interface_neighbours > neighbour_neighbour_info.interface_neighbours){
116 mass_flow = -cellC[iPop];// - descriptors::t<T,DESCRIPTOR>(iPop);
117 }else{
118 mass_flow = cell[iPop_op] - cellC[iPop];
119 }
120 }else {
121 mass_flow = cell[iPop_op];// + descriptors::t<T,DESCRIPTOR>(iPop_op);
122 }
123 }else {
124 if(!neighbour_neighbour_info.has_fluid_neighbours){
125 mass_flow = cell[iPop_op];// + descriptors::t<T,DESCRIPTOR>(iPop_op);
126 }else if(!neighbour_neighbour_info.has_gas_neighbours){
127 mass_flow = -cellC[iPop];// - descriptors::t<T,DESCRIPTOR>(iPop);
128 }else {
129 mass_flow = cell[iPop_op] - cellC[iPop];
130 }
131 }
132
133 /*
134 * Exchange depends on how filled the interfaces are
135 */
136 mass_tmp += mass_flow * 0.5 * (getClampedEpsilon(cell) + getClampedEpsilon(cellC));
137 }
138 }
139
140 cell.template setField<FreeSurface::MASS>(mass_tmp);
141
142 // Former 2 Step
143
144 // Because I need the distribution functions of the last step I will write results in a temporary
145 // array, before copying it back into the DFs
146
148
149 T curvature = 0.;
150
151 if(has_surface_tension){
153 if(info.has_gas_neighbours){
154 curvature = calculateSurfaceTensionCurvature(cell);
155 }
156
157 }
158
159 // Gas pressure adjusting
160 T gas_pressure = 1. - 6. * surface_tension_parameter * curvature;
161
162 for(int iPop=1; iPop < DESCRIPTOR::q; iPop++) {
163 auto cellC = cell.neighbor({descriptors::c<DESCRIPTOR>(iPop, 0),
164 descriptors::c<DESCRIPTOR>(iPop, 1),
165 descriptors::c<DESCRIPTOR>(iPop, 2)});
166 int iPop_op = descriptors::opposite<DESCRIPTOR>(iPop);
167
168 /*
169 * Gas replacement
170 */
171 if ( isCellType(cellC, FreeSurface::Type::Gas )) {
172 Vector<T, DESCRIPTOR::d> u_vel = cell.template getField<FreeSurface::PREVIOUS_VELOCITY>();
173 T u[DESCRIPTOR::d];
174 for(size_t u_i = 0; u_i < DESCRIPTOR::d; ++u_i){
175 u[u_i] = u_vel[u_i];
176 }
177 //T uSqr = util::normSqr<T,DESCRIPTOR::d>(u);
178 dfs[iPop_op] = equilibrium<DESCRIPTOR>::secondOrder(iPop, gas_pressure, u)
179 + equilibrium<DESCRIPTOR>::secondOrder(iPop_op, gas_pressure, u)
180 - cellC[iPop];
181 }else {
182 dfs[iPop_op] = cell[iPop_op];
183 }
184 }
185
186 for(int iPop=1; iPop<DESCRIPTOR::q; iPop++) {
187 cell[iPop] = dfs[iPop];
188 }
189
190 // Former 3 Step
191 /*
192 * Based on the mass calculation, flag this interface cell as toFluid or toGas if set boundaries are met
193 */
194 T rho = cell.computeRho();
195
196 // Check if transition needs to happen.
197 if ( mass_tmp < -transition * rho || (mass_tmp < lonely_threshold * rho && !neighbour_info.has_fluid_neighbours) ){
199 }
200 else if ( mass_tmp > (1. + transition)*rho || ( mass_tmp > (1-lonely_threshold) * rho && !neighbour_info.has_gas_neighbours) ){
202 }else if(drop_isolated_cells && (neighbour_info.interface_neighbours == 0)){
203 if(!neighbour_info.has_gas_neighbours){
205 }else if(!neighbour_info.has_fluid_neighbours){
206 //setCellFlags(cell, FreeSurface::Flags::ToGas);
207 }
208 }
209 }
210}
Plain old scalar vector.
Definition vector.h:47
void setCellFlags(CELL &cell, const FreeSurface::Flags &flags)
V getClampedEpsilon(CELL &cell)
bool isCellType(CELL &cell, const FreeSurface::Type &type)
V calculateSurfaceTensionCurvature(CELL &cell)
NeighbourInfo getNeighbourInfo(CELL &cell)
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::FreeSurface::Fluid, olb::FreeSurface::Gas, olb::FreeSurface::NeighbourInfo::has_fluid_neighbours, olb::FreeSurface::NeighbourInfo::has_gas_neighbours, olb::FreeSurface::Interface, olb::FreeSurface::NeighbourInfo::interface_neighbours, olb::equilibrium< DESCRIPTOR >::secondOrder(), olb::FreeSurface::ToFluid, and olb::FreeSurface::ToGas.

+ Here is the call graph for this function:

◆ getPriority()

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

Definition at line 57 of file freeSurfacePostProcessor3D.h.

57 {
58 return 1;
59 }

Member Data Documentation

◆ scope

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

Definition at line 55 of file freeSurfacePostProcessor3D.h.


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