OpenLB 1.7
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Public Attributes | List of all members
olb::FreeSurfaceMassFlowPostProcessor2D Class Reference

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

#include <freeSurfacePostProcessor2D.h>

+ Collaboration diagram for olb::FreeSurfaceMassFlowPostProcessor2D:

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

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 53 of file freeSurfacePostProcessor2D.h.

Member Typedef Documentation

◆ 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 55 of file freeSurfacePostProcessor2D.h.

Member Function Documentation

◆ apply()

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

Definition at line 53 of file freeSurfacePostProcessor2D.hh.

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

int olb::FreeSurfaceMassFlowPostProcessor2D::getPriority ( ) const
inline

Definition at line 67 of file freeSurfacePostProcessor2D.h.

67 {
68 return 1;
69 }

Member Data Documentation

◆ scope

constexpr OperatorScope olb::FreeSurfaceMassFlowPostProcessor2D::scope = OperatorScope::PerCellWithParameters
staticconstexpr

Definition at line 65 of file freeSurfacePostProcessor2D.h.


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